[英]Why does "not(True) in [False, True]" return False?
如果我这样做:
>>> False in [False, True]
True
那返回True
。 仅仅因为False
在列表中。
但如果我这样做:
>>> not(True) in [False, True]
False
返回False
。 而not(True)
等于False
:
>>> not(True)
False
为什么?
not x in y
被评估为x not in y
通过反汇编代码,您可以准确地看到发生了什么。 第一种情况按您的预期工作:
>>> x = lambda: False in [False, True]
>>> dis.dis(x)
1 0 LOAD_GLOBAL 0 (False)
3 LOAD_GLOBAL 0 (False)
6 LOAD_GLOBAL 1 (True)
9 BUILD_LIST 2
12 COMPARE_OP 6 (in)
15 RETURN_VALUE
第二种情况, True not in [False, True]
计算为True not in [False, True]
,这显然是False
:
>>> x = lambda: not(True) in [False, True]
>>> dis.dis(x)
1 0 LOAD_GLOBAL 0 (True)
3 LOAD_GLOBAL 1 (False)
6 LOAD_GLOBAL 0 (True)
9 BUILD_LIST 2
12 COMPARE_OP 7 (not in)
15 RETURN_VALUE
>>>
你想要表达的是(not(True)) in [False, True]
中的(not(True)) in [False, True]
,正如预期的那样是True
,你可以明白为什么:
>>> x = lambda: (not(True)) in [False, True]
>>> dis.dis(x)
1 0 LOAD_GLOBAL 0 (True)
3 UNARY_NOT
4 LOAD_GLOBAL 1 (False)
7 LOAD_GLOBAL 0 (True)
10 BUILD_LIST 2
13 COMPARE_OP 6 (in)
16 RETURN_VALUE
运算符优先级。 in
绑定比not
更紧密,因此您的表达式等效于not((True) in [False, True])
。
这完全是关于运算符优先级( in
比not
强)。 但是可以通过在正确的位置添加括号来轻松更正:
(not(True)) in [False, True] # prints true
写作:
not(True) in [False, True]
是一样的:
not((True) in [False, True])
它查看True
是否在列表中并返回结果的“not”。
它not True in [False, True]
评估为not True in [False, True]
,它返回False
因为True
在[False, True]
如果你试试
>>>(not(True)) in [False, True]
True
你得到了预期的结果。
除了提到not
的优先级低于in
的其他答案之外,实际上您的陈述等效于:
not (True in [False, True])
但请注意,如果您不将您的条件与其他条件分开,python 将使用 2 个角色( precedence
或chaining
)来将其分开,在这种情况下,python 使用优先级。 另外,请注意,如果要分隔条件,则需要将所有条件放在括号中,而不仅仅是对象或值:
(not True) in [False, True]
但如前所述,python 对链接的运算符进行了另一个修改:
基于python 文档:
请注意,比较、成员资格测试和身份测试都具有相同的优先级,并且具有如比较部分所述的从左到右的链接功能。
例如以下语句的结果是False
:
>>> True == False in [False, True]
False
因为python会链接如下语句:
(True == False) and (False in [False, True])
这正是False and True
是False
。
您可以假设中心对象将在 2 个操作和其他对象之间共享(在这种情况下为 False)。
请注意,它也适用于所有比较,包括成员测试和身份测试操作,这些操作遵循操作数:
in, not in, is, is not, <, <=, >, >=, !=, ==
例子 :
>>> 1 in [1,2] == True
False
另一个著名的例子是 number range :
7<x<20
这等于:
7<x and x<20
让我们把它看作一个集合包含检查操作: [False, True]
是一个包含一些元素的列表。
True in [False, True]
的表达式True in [False, True]
返回True
,因为True
是包含在列表中的元素。
因此, not True in [False, True]
给出了“布尔相反数”, not
上述表达式的结果(没有任何括号来保持优先级,因为in
比not
运算符具有更高的优先级)。 因此, not True
将导致False
。
另一方面, (not True) in [False, True]
等于False in [False, True]
即True
( False
包含在列表中)。
为了澄清其他一些答案,在一元运算符之后添加括号不会改变其优先级。 not(True)
不会使not
更紧密地绑定到True
。 它只是True
周围的一组冗余括号。 它与(True) in [True, False]
。 括号没有任何作用。 如果您希望绑定更紧密,则必须在整个表达式周围加上括号,这意味着运算符和操作数,即(not True) in [True, False]
。
要以另一种方式看待这一点,请考虑
>>> -2**2
-4
**
比-
结合得更紧密,这就是为什么你得到二平方的负数,而不是负二的平方(这将是正四)。
如果你确实想要负二的平方怎么办? 显然,您需要添加括号:
>>> (-2)**2
4
但是,期望以下给出4
不合理的
>>> -(2)**2
-4
因为-(2)
与-2
相同。 括号完全没有作用。 not(True)
是完全一样的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.