Python 布尔表达式与或

20 投票
4 回答
19155 浏览
提问于 2025-04-16 00:51

在Python中,如果你写了类似这样的代码:

foo==bar and spam or eggs

当布尔表达式为真时,Python会返回“spam”,如果为假则返回“eggs”。有人能解释一下这是为什么吗?为什么这个表达式没有像一个长的布尔表达式那样被评估?

补充说明:具体来说,我想弄清楚为什么“spam”或“eggs”会作为这个表达式的结果返回。

4 个回答

3

原因是,Python在判断布尔表达式时,会使用变量的实际值,而不是仅仅局限于TrueFalse这两个值。以下这些值被认为是假的:

  • None(表示没有值)
  • False(布尔假值)
  • 任何数字类型的0
  • 空的序列或集合(比如''()[]{}
  • 用户自定义类型,如果它们的__nonzero__()__len__()方法返回0或False,也会被认为是假的

想了解更多信息,可以查看Python文档中的真值测试部分。特别是:

那些返回布尔结果的操作和内置函数,通常会返回0False表示假,返回1True表示真,除非另有说明。(重要的例外是:布尔操作orand总是返回它们的一个操作数。)

6

下面是Python中的布尔运算符是怎么工作的。

根据官方文档(最后一段解释了为什么这些运算符的工作方式是个好主意):

在布尔运算的上下文中,以及在控制流语句中使用表达式时,以下值会被视为假:FalseNone、所有类型的数字零,以及空字符串和空容器(包括字符串、元组、列表、字典、集合和不可变集合)。其他所有值都被视为真。(可以查看__nonzero__()这个特殊方法,了解如何改变这一点。)

运算符not会返回True,如果它的参数是假的;如果参数是真的,则返回False

表达式x and y会先计算x;如果x是假的,就返回x的值;如果x是真的,就计算y并返回y的值。

表达式x or y同样先计算x;如果x是真的,就返回x的值;如果x是假的,就计算y并返回y的值。

(注意,andor并不限制返回的值和类型为FalseTrue,而是返回最后计算的参数。这有时很有用,比如,如果s是一个字符串,应该在它为空时用默认值替换,那么表达式s or 'foo'就能得到想要的值。因为not无论如何都要返回一个值,所以它不在乎返回的值类型和参数相同,因此例如not 'foo'会返回False,而不是''。)

20

运算符 andor 是短路运算,这意味着如果通过只看第一个操作数就能判断出结果,那么第二个操作数就不会被计算。例如,如果你有表达式 a or b,而 a 的值为真,那么 b 的值就不重要了,结果就是真,所以 b 不会被计算。它们的工作原理如下:

  • a and b: 如果 a 的值为假,那么 b 不会被计算,直接返回 a;如果 a 为真,则返回 b
  • a or b: 如果 a 的值为真,那么 b 不会被计算,直接返回 a;如果 a 为假,则返回 b

假值和真值是指在布尔上下文中被判断为假或真的值。

不过,这种 and/or 的用法在以前没有更好选择的时候很有用,但现在有更好的方法了:

spam if foo==bar else eggs

使用 and/or 的问题(除了对初学者来说可能会让人困惑)是,如果条件为真但 spam 计算出的值是个假值(比如空字符串),那么结果就会错误。因此,最好避免使用这种写法。

撰写回答