评估数值表达式

3

请问有人能解释一下为什么在评估数值表达式时,Python返回最后一个被评估的东西作为结果吗?

例如:

3 and 5

评估为

5

我有另一个问题,为什么它会评估这些表达式,当我尝试检查时:
3 == True

当我执行以下代码时,得到的结果是 False:

3 and 5

当它返回5作为结果时,很明显(我认为)它认为3的值为真,因为如果它认为否则,它就不会继续评估(在这里我可能是错的)。相反,当我评估:

0 and 3

我得到了0,我认为发生的事情是Python检查0是否为真,决定它不是并将其输出。
抱歉如果听起来有点混乱,但我在我的书中偶然发现这个问题,想知道是否有我所忽略的东西。

1
这里有一些非常好的答案:https://dev59.com/D2865IYBdhLWcg3wat6l - NullUserException
2
此外,这种行为在这里有记录:http://docs.python.org/reference/expressions.html#and - NullUserException
谢谢,我发现这里也包含了一些很好的答案:https://dev59.com/enA75IYBdhLWcg3wqKx0 - Blücher
3个回答

3

是的,在Python中,任何值都是真值或假值。每个整数都是真值,除了0。使用布尔运算符orand,Python返回它评估的最后一个表达式,例如3 or 5将返回3,因为Python首先看到3是真值,不必评估5,然后返回3。

在0 and 5中,0是假值,因此Python不会评估下一个表达式,并返回0。

5 == True之所以返回False,是因为5不等于true,它只是在布尔表达式中表现为真值。bool(5) == True返回True,因为这将整数显式转换为布尔值。


不需要谈论“原始类型”(更别提它们通常被称为内置类型,因为“原始”与限制和优势相关,而这些并不适用于Python)。每个对象都有一个真值。 - user395760
不确定是否有可能拥有没有真值的对象。 - Andrew Marsh
好的,似乎可以在__nonzero__(负责转换为布尔值的方法)中抛出异常,从而在决定真假值之前终止执行,但默认实现不会这样做,理智的人也不会这样做。此外,这可能只是具有未定义的真假值,而不是根本没有值。 - user395760
@AndrewMarsh,谢谢你。但是我不能接受这个答案,因为它没有回答我的原始问题,而我已经找到了答案。 - Blücher
@AndrewMarsh,对象可能没有真值:“用户定义的对象可以通过提供__bool__()方法来自定义它们的真值。”因此,如果没有为对象定义这样的方法,则评估其真值可能默认为True或False,或者可能会引发异常:-)。 - Dave

2

来自Python参考文档:

The expression x and y first evaluates x; if x is false, its value is returned;
otherwise, y is evaluated and the resulting value is returned.

如果您说过
0 and 5

对于第一个问题,如果使用逗号操作符分隔表达式,则将依次计算每个子表达式,并返回最后一个表达式的值。在这种情况下,将计算0和(1 + 2),但仅返回(1 + 2)的结果。

对于第二个问题,当作为布尔值处理时,3显然评估为true,但 == 运算符在比较之前不会强制将其参数转换为布尔值。


你的最后一句话是错误的。1 == True0 == False 都是 True - NullUserException
1
@NullUserException - 这是一个灰色地带。在 1 == True 中没有强制转换参数,True确实会评估为1。尝试这个:list((x % 2 == 1) for x in range(10)),你会得到 [False, True, False, True, False, True, False, True, False, True]。现在将 list 更改为 sum,你会得到5,因为True确实等于1,而False等于0。 - PaulMcG
@PaulMcGuire 那不进一步证明了存在强制转换,既从整数到布尔值,又从布尔值到整数吗? - NullUserException
3 == 5 是错误的,即使3和5在强制转换为布尔值后会有相同的结果。原帖中的语句3==True评估为False是正确的,令人惊讶的是,==运算符将其强制转换为数字而不是布尔值!0==True -> False. 1==True -> True. 2==True -> False. 3==True -> False. - Dave
@NullUserExceptionఠ_ఠ 1.0 == True 的结果是True,1.1 == True 的结果是False,0.9 == True 和 0.9 == False 的结果也都是False。因此,强制转换既不是整数,也不是布尔值,这与我最初的说法不同。 - Dave
1
@NullUserException - 不,这意味着True和False具有1和0的数值。 3 == True 的计算结果为False,因此没有强制转换。您必须明确表示要使用 bool(3) == True 来获取3的布尔值,其计算结果为True。 - PaulMcG

0

布尔运算的工作原理

请参阅布尔运算文档。它们的工作方式如下:

  • a or b 返回第一个被评估为True的元素,因此在0或3的情况下,它将是3,而在3或5的情况下,它也将是3
  • a and b 返回第一个被评估为False的元素,否则(如果所有元素都被评估为True),则返回最后一个元素,因此0和3将变成03和5将变成5

解决方案

但是,您的问题有解决方案。只需使用bool()将结果转换为布尔值即可:

>>> bool(0 or 3)
True
>>> bool(3 or 5)
True
>>> bool(0 and 3)
False
>>> bool(3 and 5)
True

有帮助吗?

编辑:

另一种解决方案

实际上,我认为在您的情况下,可能有更好的解决方案。请看这个:

  • bool(a or b) 可以被替换为 any([a, b]),并且
  • bool(a and b) 可以被替换为 all([a, b])

我现在相信这是一个更合理的解决方案。


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