为什么“ [False,True]中的not(True)”返回False?


483

如果我这样做:

>>> False in [False, True]
True

那又回来了True。仅仅是因为False在列表中。

但是如果我这样做:

>>> not(True) in [False, True]
False

那又回来了False。而not(True)等于False

>>> not(True)
False

为什么?



2
您的括号令人困惑not(True) in [False, True]
Grijesh Chauhan

Answers:


730

运算符优先级 2.x3.x。的优先级not低于的优先级in。因此,它等效于:

>>> not ((True) in [False, True])
False

这就是你想要的:

>>> (not True) in [False, True]
True

正如@Ben指出的:建议从不写not(True),而不是not True。前者使它看起来像一个函数调用,而它却not是一个运算符,而不是一个函数。


279
@ Texom512:我也建议不要写not(True);喜欢not True。第一种使它看起来像函数调用,这正是您产生困惑的地方。如果not是一个函数,则not(True) in ...不可能是not ((True) in ...)。您必须知道它是一个运算符(否则您最终会遇到这种情况),因此您应该像一个运算符一样编写它,而不要将其伪装成函数。

7
另外,如果您打算使用空格来表示优先级以使读者受益,请首先确保您是正确的。写可能没问题,写a + b*c + d很不好a+b * c+d。因此not(True)按这种方法也是不好的。
史蒂夫·杰索普

32
实际上,永远不要not True。写吧False
Darkhogg

10
大概在现实生活中你不会写not True,而会写一些返回或函数的not myfunc(x,y,z)地方。myfuncTrueFalse
Nate CK

3
@ BenC.R.Leggiero这就是我在原始答案中所做,其他人已经纠正了它。当前的版本对我来说已经足够清楚了,如果没有多余的括号,我认为很难理解,因为指出了关键问题,理解其余内容是程序员的基本技能。
于昊

76

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        

13
总是有一个家伙,dis但这是一个非常有价值的答案,因为它表明实际上not in已在使用
jamylak

21
字节码是CPython解释器的实现细节。这是对Python问题的CPython答案,实际上可以直接从语言参考中得到更好的答案。
2015年

5
@wim我认为字节码实现并不像实际的反汇编那么重要。确保其他实现会生成功能上完全相同的内容,因此了解一个反汇编可提供足够的洞察力,以了解“为什么”而不是底层的“如何”。
Alex Pana

36

运算符优先级。in绑定比紧密not,因此您的表达式等效于not((True) in [False, True])


33

一切都与运算符优先级有关in比强大not)。但是可以通过在适当的位置添加括号来轻松地纠正它:

(not(True)) in [False, True]  # prints true

写作:

not(True) in [False, True]

就像这样:

not((True) in [False, True])

它看起来是否True在列表中,并返回结果的“ not”。


14

它的计算结果为not True in [False, True]False由于True位于中而返回[False, True]

如果你试试

>>>(not(True)) in [False, True]
True

您会得到预期的结果。


13

除了提到优先级not低于的其他答案in,实际上您的陈述还等同于:

not (True in [False, True])

但请注意,如果您不将条件与其他条件分开,则python将使用2个角色(precedencechaining)将其分开,在这种情况下,python使用优先级。另外,请注意,如果要分隔条件,则需要将所有条件放在括号中,而不仅是对象或值:

(not True) in [False, True]

但是如前所述,python对运算符进行了另一种修改,即链接

基于python 文档

请注意,比较,成员资格测试和身份测试均具有相同的优先级,并且具有“比较”部分中所述的从左到右的链接功能。

例如,以下语句的结果是False

>>> True == False in [False, True]
False

因为python将像下面这样链接语句:

(True == False) and (False in [False, True])

确切的False and TrueFalse

您可以假定中心对象将在2个操作和其他对象之间共享(在这种情况下为False)。

并注意,对于所有比较,包括隶属度测试和身份测试操作(其后为操作数),它也适用:

in, not in, is, is not, <, <=, >, >=, !=, ==

范例:

>>> 1 in [1,2] == True
False

另一个著名的例子是数字范围:

7<x<20

等于:

7<x and x<20   

6

让我们将其视为集合包含检查操作:[False, True]是包含一些元素的列表。

表达式True in [False, True]返回True,就像True列表中包含的元素一样。

因此,not True in [False, True]给出not上述表达式的“布尔相反” (没有任何括号可保留优先级,因为in优先级大于not运算符)。因此,not True将导致False

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


6

为了阐明其他一些答案,一元运算符添加括号不会更改其优先级。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)完全一样

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.