为什么 "not(True) in [False, True]" return 是假的?
Why does "not(True) in [False, True]" return False?
如果我这样做:
>>> False in [False, True]
True
即returnsTrue
。仅仅因为 False
在列表中。
但如果我这样做:
>>> not(True) in [False, True]
False
即returnsFalse
。而 not(True)
等于 False
:
>>> not(True)
False
为什么?
运算符优先级。 in
比 not
绑定得更紧密,所以你的表达式等同于 not((True) in [False, True])
.
都是关于operator precedence(in
比not
强)。但是可以通过在正确的地方添加括号来轻松更正:
(not(True)) in [False, True] # prints true
写作:
not(True) in [False, True]
等于:
not((True) in [False, True])
查找 True
是否在列表中以及 returns 结果的 "not"。
运算符优先级 2.x, 3.x。 not
的优先级低于in
的优先级。所以相当于:
>>> not ((True) in [False, True])
False
这就是你想要的:
>>> (not True) in [False, True]
True
正如@Ben 指出的那样:建议永远不要写 not(True)
,最好写 not True
。前者让它看起来像一个函数调用,而 not
是一个运算符,而不是函数。
它被评估为 not True in [False, True]
,returns False
因为 True
在 [False, True]
如果你尝试
>>>(not(True)) in [False, True]
True
你得到了预期的结果。
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]
,显然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]
,果然是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
让我们把它看作一个集合包含检查操作:[False, True]
是一个包含一些元素的列表。
表达式 True in [False, True]
returns True
,因为 True
是列表中包含的一个元素。
因此,not True in [False, True]
给出上述表达式的 "boolean opposite"、not
结果(不带任何括号以保留优先级,因为 in
的优先级高于 not
运算符)。
因此,not True
将导致 False
。
另一方面,(not True) in [False, True]
等于False in [False, True]
,即True
(False
包含在列表中)。
除了提到 not
的优先级低于 in
的其他答案外,实际上您的陈述等同于:
not (True in [False, True])
但请注意,如果您不将您的条件与其他条件分开,python 将使用 2 个角色(precedence
或 chaining
)来将其分开,并且在这种情况下 python 使用了优先级。另外,请注意,如果要分隔条件,则需要将所有条件放在括号中,而不仅仅是对象或值:
(not True) in [False, True]
但如前所述,python 对运算符进行了另一个修改,即 chaining:
基于 python documentation :
Note that comparisons, membership tests, and identity tests, all have the same precedence and have a left-to-right chaining feature as described in the Comparisons section.
例如下面语句的结果是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
另一个著名的例子是数字范围:
7<x<20
等于:
7<x and x<20
为了澄清其他一些答案,在一元运算符之后添加括号不会改变其优先级。 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)
完全一样。
如果我这样做:
>>> False in [False, True]
True
即returnsTrue
。仅仅因为 False
在列表中。
但如果我这样做:
>>> not(True) in [False, True]
False
即returnsFalse
。而 not(True)
等于 False
:
>>> not(True)
False
为什么?
运算符优先级。 in
比 not
绑定得更紧密,所以你的表达式等同于 not((True) in [False, True])
.
都是关于operator precedence(in
比not
强)。但是可以通过在正确的地方添加括号来轻松更正:
(not(True)) in [False, True] # prints true
写作:
not(True) in [False, True]
等于:
not((True) in [False, True])
查找 True
是否在列表中以及 returns 结果的 "not"。
运算符优先级 2.x, 3.x。 not
的优先级低于in
的优先级。所以相当于:
>>> not ((True) in [False, True])
False
这就是你想要的:
>>> (not True) in [False, True]
True
正如@Ben 指出的那样:建议永远不要写 not(True)
,最好写 not True
。前者让它看起来像一个函数调用,而 not
是一个运算符,而不是函数。
它被评估为 not True in [False, True]
,returns False
因为 True
在 [False, True]
如果你尝试
>>>(not(True)) in [False, True]
True
你得到了预期的结果。
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]
,显然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]
,果然是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
让我们把它看作一个集合包含检查操作:[False, True]
是一个包含一些元素的列表。
表达式 True in [False, True]
returns True
,因为 True
是列表中包含的一个元素。
因此,not True in [False, True]
给出上述表达式的 "boolean opposite"、not
结果(不带任何括号以保留优先级,因为 in
的优先级高于 not
运算符)。
因此,not True
将导致 False
。
另一方面,(not True) in [False, True]
等于False in [False, True]
,即True
(False
包含在列表中)。
除了提到 not
的优先级低于 in
的其他答案外,实际上您的陈述等同于:
not (True in [False, True])
但请注意,如果您不将您的条件与其他条件分开,python 将使用 2 个角色(precedence
或 chaining
)来将其分开,并且在这种情况下 python 使用了优先级。另外,请注意,如果要分隔条件,则需要将所有条件放在括号中,而不仅仅是对象或值:
(not True) in [False, True]
但如前所述,python 对运算符进行了另一个修改,即 chaining:
基于 python documentation :
Note that comparisons, membership tests, and identity tests, all have the same precedence and have a left-to-right chaining feature as described in the Comparisons section.
例如下面语句的结果是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
另一个著名的例子是数字范围:
7<x<20
等于:
7<x and x<20
为了澄清其他一些答案,在一元运算符之后添加括号不会改变其优先级。 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)
完全一样。