为什么“不(真)在”返回假?
如果我这样做:
>>> 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)
是完全一样的。