如果我这样做:
>>> False in [False, True] True
返回True。很简单,因为False在列表中。
True
False
但如果我这样做了:
>>> not(True) in [False, True] False
返回False。而not(True)等于False:
not(True)
>>> not(True) False
为什么?
运算符优先级。in比not绑定更紧密,所以你的表达式等价于not((True) in [False, True])。
in
not
not((True) in [False, True])
这都是关于运算符优先级 (in比not更强)。但只要在正确的位置加上括号,就可以很容易地纠正这个错误:
(not(True)) in [False, True] # prints true
写作:
not(True) in [False, True]
是一样的:
它查看True是否在列表中,并返回结果的“not”。
运算符优先级 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
它的值是not True in [False, True],返回False,因为True在[False, True]中
not True in [False, True]
[False, True]
如果你尝试
>>>(not(True)) in [False, True] True
你得到了预期的结果。
not x in y的值为x not in y
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:
True not in [False, True]
>>> 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,你可以看到原因:
(not(True)) in [False, 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]返回True,因为True是包含在列表中的元素。
True in [False, True]
另一方面,(not True) in [False, True]等于False in [False, True],也就是True (False包含在列表中)。
(not True) in [False, True]
False in [False, True]
除了其他提到not的优先级低于in的答案外,实际上您的语句等价于:
not (True in [False, True])
但请注意,如果你不将你的条件与其他条件分离,python将使用2个角色(precedence或chaining)来分离它们,在这种情况下,python使用优先级。另外,请注意,如果你想分离一个条件,你需要把所有的条件都放在括号里,而不仅仅是对象或值:
precedence
chaining
但如前所述,python对操作符的另一个修改是链接:
基于python < em > < / em >文档:
请注意,比较、成员测试和身份测试都具有相同的优先级,并且具有从左到右的链接特性,如比较部分所述。
例如,下面语句的结果是False:
>>> True == False in [False, True] False
因为python会像下面这样链接语句:
(True == False) and (False in [False, True])
也就是False and True,也就是False。
False and True
您可以假设中心对象将在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]。
(True) in [True, False]
(not True) in [True, False]
从另一个角度来看,考虑一下
>>> -2**2 -4
**比-绑定得更紧密,这就是为什么你得到的是- 2的平方,而不是- 2的平方(这将是正4)。
**
-
如果你想要- 2的平方呢?显然,你要加上括号:
>>> (-2)**2 4
然而,期望下面的对象给出4是不合理的
4
>>> -(2)**2 -4
因为-(2)与-2相同。括号完全没有任何作用。not(True)完全相同。
-(2)
-2