32

正如所料,空元组不包含 1

>>> 1 in ()
False

False返回的值不等于False

>>> 1 in () == False
False

换一种方式来看,in运算符返回一个bool既不是True也不是False

>>> type(1 in ())
<type 'bool'>
>>> 1 in () == True, 1 in () == False
(False, False)

但是,如果原始表达式被括号括起来,则恢复正常行为

>>> (1 in ()) == False
True

或者它的值存储在一个变量中

>>> value = 1 in ()
>>> value == False
True

在 Python 2 和 Python 3 中都观察到了这种行为。

你能解释一下发生了什么吗?

4

1 回答 1

45

您遇到了比较运算符链接;1 in () == False不代表。_ _(1 in ()) == False

相反,比较是链式的,表达式的真正含义是:

(1 in ()) and (() == False)

因为(1 in ())已经是假的,所以链式表达式的后半部分被完全忽略(因为False and something_else返回False任何值something_else)。

请参阅比较表达式文档

比较可以任意链接,例如,x < y <= z等价于x < y and y <= z,除了y只评估一次(但在两种情况下,当发现为假z时根本不评估)。x < y

作为记录,<, >, ==, >=, <=, !=, is,is not和都是比较运算符(不推荐使用的in)。not in<>

一般来说,不要与布尔值比较;只需测试表达式本身。如果您必须针对布尔文字进行测试,至少使用括号和is运算符,True并且False是单例,就像None

>>> (1 in ()) is False
True

当涉及整数时,这会变得更加混乱。Pythonbool类型是 1 的子int。如此,False == 0是真实的,是真实的True == 1。因此,您可以想象创建看起来很正常的链式操作:

3 > 1 == True

是真的,因为3 > 11 == True都是真的。但是表达式:

3 > 2 == True

是假的,因为2 == True是假的。

1历史原因的子类;Python 并不总是像 C 那样具有类型和具有布尔含义的重载整数。制作子类可以让旧代码继续工作。 boolintboolbool

于 2013-11-03T09:41:08.270 回答