Python中的“x = y或z”赋值语句是什么意思?

23

为什么我们会看到使用or的Python赋值语句?

例如:

def my_function(arg_1=None, arg_2=0):
    determination = arg_1 or arg_2 or 'no arguments given!'
    print(determination)
    return determination

当没有参数传递给上述函数时,该函数将打印并返回字符串 'no arguments given!'
Python为何这样做?如何最好地利用这个功能呢?
1个回答

37

"or"表达式在赋值中的作用:

有时我们在Python中看到这种表达式被用作三元赋值表达式的替代品,(实际上,这启发了语言添加条件语句)。

x = a or b

如果bool(a)返回False,那么x将被赋值为b

条件表达式的相同用例(即三元赋值)

以下是一个这样的条件表达式的示例,它完成了相同的事情,但可能少了一些神秘感。
def my_function(arg_1=None, arg_2=0):
    determination = arg_1 if arg_1 else arg_2 if arg_2 else 'no arguments given!'
    print(determination)
    return determination

重复使用这种语法被认为是不好的风格,但对于一行代码来说还可以接受。缺点是这有些重复。

or表达式

基本情况下,x or y返回x如果bool(x)评估为True,否则它会评估y,(参见文档以供参考)。因此,一系列or表达式的效果是返回第一个评估为True的项目,或者最后一个项目。

例如

'' or [] or 'apple' or () or set(['banana'])

返回'apple',第一个被评估为True的项目,并且

'' or [] or ()

() 返回,即使它被评估为 False

扩展的 and 用法

相比之下,如果 bool(x) 评估为 Falsex and y 会返回 x,否则将返回 y

当您考虑到条件 and 系列中的所有条件都需要评估为 True 才能继续沿着该路径进行控制流时,使用这种方式是有意义的,并且在遇到一个为 False 的条目时继续评估这些条目是没有意义的。

使用 and 进行赋值的效用并不像使用 or 那么明显,但在历史上它被用于三元赋值。也就是说,在这种更清晰和直接的结构可用之前:

a = x if condition else y

布尔运算符组成的等价形式是:
a = condition and x or z                      # don't do this!

这段话虽然可以通过全面理解Python的andor运算来推导出含义,但不如三元条件表达式易读,最好完全避免使用。

结论

使用布尔表达式进行赋值必须小心谨慎。绝对不要使用and进行赋值,因为这样很容易引起混淆而产生错误。风格专家可能会发现使用or进行赋值不如更冗长的三元表达式if condition else优秀,但我发现它在专业Python社区中非常普遍,可以被视为惯用语。

如果您选择使用它,请小心谨慎,并了解到达的最终元素将始终被返回,无论其评估结果如何,因此该最终元素应该是一个字面量,以便您知道变量有一个良好的默认回退值。


很棒的回答! 我想争辩一下,您不应该说某些东西是否评估为“True”或“False”,而是要看它是否为真。 b = 1 or 2 意味着 b == 1,但两者都不是“True”。也许我只是过分追求细节,或者甚至有点困惑? - 2rs2ts
1
显然,我的表述不够清晰。:) b = 1 or 2 的意思是它首先计算 or 前面的项,如果在布尔上下文中评估为 True,则返回该值。我会尽快在文本中澄清。同时,请查看以下文档:http://docs.python.org/2/reference/expressions.html#boolean-operations 查找以“表达式x或y首先计算x;如果x为真,则返回其值;否则,...”开头的文本。 - Russia Must Remove Putin
哦,是的,我知道这些。我只是对类型有点挑剔。 - 2rs2ts

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接