为什么“不(真)在”返回假?
如果我这样做:
>>> False in [False, True] True
这返回True 。 只是因为False在列表中。
但是,如果我这样做:
>>> not(True) in [False, True] False
那返回False 。 而not(True)等于False :
>>> not(True) False
为什么?
运算符优先级 2.x , 3.x 。 优先级not低于in 。 所以它相当于:
>>> not (True in [False, True]) False
这是你想要的:
>>> (not True) in [False, True] True
正如@Ben所指出的那样:build议不要写not(True) , not True 。 前者使得它看起来像一个函数调用,而not一个操作符,而不是一个函数。
not x in y中的x not 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 >>>
你想要expression的是(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
运算符优先级 in绑定比not更紧密,所以你的expression等于not((True) in [False, True]) 。
这一切都是关于运营商的优先级 (比not强)。 但是可以通过在正确的位置添加括号来轻松地进行纠正:
(not(True)) in [False, True] # prints true
写作:
not(True) in [False, True]
是一样的:
not((True) in [False, True])
看起来如果True是在列表中,并返回结果的“不”。
它not True in [False, True]评估为not True in [False, True] ,返回False因为True在[False, True]
如果你试试
>>>(not(True)) in [False, True] True
你会得到预期的结果。
除了其他答案中提到的优先级not低于,实际上你的语句相当于:
not (True in [False, True])
但是请注意,如果你不把你的条件与其他条件分开,python将使用2个angular色( precedence或chaining )来区分,在这种情况下,python使用优先级。 此外,请注意,如果要分隔条件,则需要将所有条件放在括号中,而不仅仅是对象或值:
(not True) in [False, True]
但是正如前面提到的那样,python对运营商进行了另外一个修改:
基于python 文档 :
请注意,比较,成员身份testing和身份testing都具有相同的优先级,并具有“比较”部分中所述的从左至右的链接function。
例如下面语句的结果是False :
>>> True == False in [False, True] False
因为python会链接如下的语句:
(True == False) and (False in [False, True])
False and True是False 。
您可以假定中央对象将在2个操作和其他对象之间共享(在这种情况下为False)。
并且请注意,对所有比较来说也是如此,包括后续操作数的成员testing和身份testing操作:
in, not in, is, is not, <, <=, >, >=, !=, ==
例如:
>>> 1 in [1,2] == True False
另一个着名的例子是数字范围:
7<x<20
这等于:
7<x and x<20
让我们看看它是一个集合包含检查操作: [False, True]是一个包含一些元素的列表。
True in [False, True]的expression式返回True ,因为True是包含在列表中的元素。
因此, not True in [False, True]给出了“布尔相反”, not上述expression式的结果(没有任何括号来保留优先权,因为in比not运算符具有更高的优先权)。 因此, not True会导致False 。
另一方面, (not True) in [False, True]等于False in [False, True] ,这是True ( False包含在列表中)。
为了澄清其他一些答案, 在一元运算符之后添加括号不会改变它的优先级。 not(True)不会使True与True绑定更紧密。 这只是一个冗余的圆括号。 (True) in [True, False]与(True) in [True, False]大致相同。 括号不做任何事情。 如果你希望绑定更加紧凑,你必须在整个expression式中加上括号,这就是操作符和操作数,即(not True) in [True, False] 。
换一种方式来看看,考虑一下
>>> -2**2 -4
**比-更紧-这就是为什么你得到两个平方的负数,而不是负二的平方(这将是正四)。
如果你想要两个正方形呢? 显然,你会添加括号:
>>> (-2)**2 4
但是,期望下面给出4不合理的
>>> -(2)**2 -4
因为-(2)与-2相同。 括号完全没有。 not(True)是完全一样的。