Python布尔表达式和或

时间:2010-07-05 20:09:30

标签: python syntax boolean-expression

在python中如果你写了类似

的东西
foo==bar and spam or eggs
如果布尔语句为true,那么

python似乎返回垃圾邮件,否则返回egg。有人可以解释这种行为吗?为什么表达式没有被评估为像一个长布尔值?

编辑:具体来说,我正在试图弄清楚为什么'垃圾邮件'或'鸡蛋'因表达而被退回的机制。

4 个答案:

答案 0 :(得分:18)

运算符andor是短路的,这意味着如果表达式的结果可以仅通过评估第一个操作数来推断,则不会计算第二个操作数。例如,如果表达式a or ba的计算结果为true,那么b是什么并不重要,表达式的结果为真,因此b不是评估。它们的实际工作如下:

  • a and b:如果a为假,则不评估b并返回a,否则返回b。
  • a or b:如果a是真实的,则不评估b并返回a,否则返回b。

Falsey和truthy引用在布尔上下文中求值为false或true的值。

然而,在没有更好的选择的日子里,这个和/或成语很有用,但现在有更好的方法:

spam if foo==bar else eggs

和/或习语的问题(除了让初学者感到困惑)是,如果条件为真,它会给出错误的结果,但垃圾邮件评估为假值(例如空字符串)。出于这个原因,你应该避免它。

答案 1 :(得分:5)

这是Python布尔运算符的工作方式。

来自the documentation(最后一段解释了为什么操作员按照他们的方式工作是个好主意):

  

在布尔运算的上下文中,   以及何时使用表达式   控制流程语句,如下   值被解释为false:   FalseNone,数字为零   类型,空字符串和   容器(包括字符串,元组,   列表,词典,集和   frozensets)。所有其他值都是   解释为真。 (见   __nonzero__()一种更改此方法的特殊方法。)

     

如果运营商not产生True   参数为false,否则为False

     

表达式x and y首先进行评估   x;如果x为false,则其值为   回;否则,评估y   并返回结果值。

     

表达式x or y首先进行评估   x;如果x为真,则其值为   回;否则,评估y   并返回结果值。

     

(请注意,andor都不受限制   他们返回的价值和类型   FalseTrue,而是返回   最后评估的论点。这是   有时候很有用,例如,如果s是a   应该由a替换的字符串   默认值,如果它是空的,   表达式s or 'foo'产生了   期望值。因为not必须这样做   无论如何发明一个价值,它没有   懒得返回相同的值   键入作为参数,例如,not 'foo'产生False,而不是''。)

答案 2 :(得分:3)

原因是Python使用所涉及变量的实际值来评估布尔表达式,而不是将它们限制为TrueFalse值。以下值被视为错误:

  • None
  • False
  • 0的任何数字类型
  • 空序列或集(''()[]{}
  • 使用__nonzero__()__len__()方法返回0或False
  • 的用户定义类型

有关详细信息,请参阅Python文档的Truth Value Testing部分。特别是:

  

具有布尔结果的操作和内置函数始终返回0False表示false,1True表示true,除非另有说明。 (重要的例外:布尔运算orand总是返回其中一个操作数。)

答案 3 :(得分:2)

尝试使用括号使表达式不明确。就是这样,你得到了:

(foo == bar and spam) or eggs