不带 else 的 Python 三元运算符

问题描述 投票:0回答:9

是否可以在 Python 中的一行中完成此操作?

if <condition>:
    myList.append('myString')

我尝试过三元运算符:

myList.append('myString' if <condition>)

但是我的 IDE (MyEclipse) 不喜欢它,没有

else

python ternary
9个回答
160
投票

是的,你可以这样做:

<condition> and myList.append('myString')

如果

<condition>
为 false,则将启动短路并且不会评估右侧。如果
<condition>
为 true,则将计算右侧并附加该元素。

我只是指出,执行上述操作是非常非Pythonic的,无论如何,最好写这个:

if <condition>: myList.append('myString')

演示:

>>> myList = []
>>> False and myList.append('myString')
False
>>> myList
[]
>>> True and myList.append('myString')
>>> myList
['myString']

63
投票

该语言不允许您使用语法的原因

variable = "something" if a_condition

没有

else
是指,在
a_condition == False
的情况下,
variable
突然变得未知。也许它可以默认为
None
,但 Python 要求所有变量赋值实际上都会导致显式赋值。这也适用于函数调用等情况,因为传递给函数的值的计算方式与赋值语句的 RHS 相同。

同样,所有

return
都必须实际返回,即使它们是有条件的
return
。例如:

return variable if a_condition

是不允许的,但是

return variable if a_condition else None

是允许的,因为第二个示例保证显式返回某些内容。


15
投票
if <condition>: myList.append('myString')

否则,不行。为什么需要把它放在一行上?

请注意,“三元运算符”是一个 运算符。与任何运算符一样,它必须返回某些内容,那么如何才能拥有没有

else
子句的三元运算符呢?如果条件不成立,它应该返回什么?


12
投票

您基本上是在要求

do_thing() if <condition> else pass
构造(如果运行,它将抛出
SyntaxError
)。正如我在研究(某种程度上)类似问题
do_thing() if condition else None
时发现的那样,它是尽可能接近的(这只是另一种方法
<condition> and do_thing()
)。因此,总结一下这个想法和其他答案,以下是您的选择:

  • if <condition>: myList.append('myString')
    ——似乎是最不“hacky”(因此是首选)的方式
  • <condition> and myList.append('myString')
  • myList.append('myString') if <condition> else None

3
投票

myList.extend(['myString'] if condition else [])
也可以,尽管它比其他解决方案需要更多工作。


3
投票

如果我想根据条件将可选元素添加到列表中,我就会这样做。

nums = [
        1,
        2,
        3 if <condition> else None,
        4,
       ]

# nums now contains values of `None`, so we delete all occurrences of `None`
nums.remove(None)

如果不满足条件,这只是用 None 替换该值,然后,它只是重新定义没有 None 值的列表。 这样,如果满足条件,他们会保留索引


1
投票

您可以执行如下操作。请注意,

None
永远不会附加到
myList

myList.append('myString') if <condition> else None

此外,Python 应该接受下面的单行代码。

if <condition>: myList.append('myString')

0
投票

对于所有问“为什么要这样做?”的人来说,在一种情况下该语法将非常有用。

获取此代码:

class a:
    def calla(self):
        print("a")

class b:
    def callb(self):
        print("b")

def c(*args):

    class c(a if args[0], b if args[1]):
        def __init__(self, *args):
            self.calla = getattr(self, "calla", None)
            if callable(self.calla):
                self.calla()
                
            self.callb = getattr(self, "callb", None)
            if callable(self.callb):
                self.callb()
                
    return c(args[2:])

C = c(False, False)

代码尝试有条件地继承类 a 和/或/nor b。 getattr 和 callable 行检查类 a 或 b 的方法是否存在,即类是否成功继承。 工厂函数用于定义赋予类 c 的继承条件。 最后,类 c 的继承定义中有条件。

不幸的是,这段代码无法运行,因为 if 之后必须有一个 else...它无法避免使用一行 if 语句,因为以“if”开头的语法无效。

您也不能像这样继承对象:

class c(a if args[0] else object, b if args[1] else object):

如果 a 或 b 都不需要继承,这段代码可能会抛出继承“object”两次的错误。 (“else None”和“else c”当然也不起作用)

因此,避免这种情况的方法是为 a 和 b 创建内部没有任何内容的一次性类,但这看起来很糟糕并且似乎是错误的......

class a:
    def calla(self):
        print("a")

class b:
    def callb(self):
        print("b")

class empty:
    pass
class empty2:
    pass

def c(*args):
    
    class c(a if args[0] else empty, b if args[1] else empty2):
        def __init__(self, *args):
            self.calla = getattr(self, "calla", None)
            if callable(self.calla):
                self.calla()
                
            self.callb = getattr(self, "callb", None)
            if callable(self.callb):
                self.callb()
                
    return c(args[2:])

C = c(False, False)

因此,让三元运算符不需要 else 会很有用。


-1
投票
def map_key_vs_values(db, key_name, val_name):
    _map = {}
    for item in db:
        p = item[key_name]
        a = item[val_name]

        try: a not in _map[p] and _map[p].append(a)
        except: _map[p] = [a]
        
    return _map
© www.soinside.com 2019 - 2024. All rights reserved.