为什么“不(真)在”返回假?

如果我这样做:

>>> 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色( precedencechaining )来区分,在这种情况下,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 TrueFalse

您可以假定中央对象将在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式的结果(没有任何括号来保留优先权,因为innot运算符具有更高的优先权)。 因此, not True会导致False

另一方面, (not True) in [False, True]等于False in [False, True] ,这是TrueFalse包含在列表中)。

为了澄清其他一些答案, 一元运算符之后添加括号不会改变它的优先级。 not(True)不会使TrueTrue绑定更紧密。 这只是一个冗余的圆括号。 (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)是完全一样的。