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

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

如果我这样做:

>>> False in [False, True]
True

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

但是如果我这样做:

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

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

>>> not(True)
False

为什么?

If I do this:

>>> False in [False, True]
True

That returns True. Simply because False is in the list.

But if I do:

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

That returns False. Whereas not(True) is equal to False:

>>> not(True)
False

Why?


回答 0

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

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

这就是你想要的:

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

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

Operator precedence 2.x, 3.x. The precedence of not is lower than that of in. So it is equivalent to:

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

This is what you want:

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

As @Ben points out: It’s recommended to never write not(True), prefer not True. The former makes it look like a function call, while not is an operator, not a function.


回答 1

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        

not x in y is evaluated as x not in y

You can see exactly what’s happening by disassembling the code. The first case works as you expect:

>>> 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

The second case, evaluates to True not in [False, True], which is False clearly:

>>> 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        
>>> 

What you wanted to express instead was (not(True)) in [False, True], which as expected is True, and you can see why:

>>> 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        

回答 2

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

Operator precedence. in binds more tightly than not, so your expression is equivalent to not((True) in [False, True]).


回答 3

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

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

写作:

not(True) in [False, True]

就像这样:

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

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

It’s all about operator precedence (in is stronger than not). But it can be easily corrected by adding parentheses at the right place:

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

writing:

not(True) in [False, True]

is the same like:

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

which looks if True is in the list and returns the “not” of the result.


回答 4

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

如果你试试

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

您会得到预期的结果。

It is evaluating as not True in [False, True], which returns False because True is in [False, True]

If you try

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

You get the expected result.


回答 5

除了提到优先级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   

Alongside the other answers that mentioned the precedence of not is lower than in, actually your statement is equivalent to :

not (True in [False, True])

But note that if you don’t separate your condition from the other ones, python will use 2 roles (precedence or chaining) in order to separate that, and in this case python used precedence. Also, note that if you want to separate a condition you need to put all the condition in parenthesis not just the object or value :

(not True) in [False, True]

But as mentioned, there is another modification by python on operators that is chaining:

Based on python documentation :

Note that comparisons, membership tests, and identity tests, all have the same precedence and have a left-to-right chaining feature as described in the Comparisons section.

For example the result of following statement is False:

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

Because python will chain the statements like following :

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

Which exactly is False and True that is False.

You can assume that the central object will be shared between 2 operations and other objects (False in this case).

And note that its also true for all Comparisons, including membership tests and identity tests operations which are following operands :

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

Example :

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

Another famous example is number range :

7<x<20

which is equal to :

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被包含在列表中)。

Let’s see it as a collection containment checking operation: [False, True] is a list containing some elements.

The expression True in [False, True] returns True, as True is an element contained in the list.

Therefore, not True in [False, True] gives the “boolean opposite”, not result of the above expression (without any parentheses to preserve precedence, as in has greater precedence than not operator). Therefore, not True will result False.

On the other hand, (not True) in [False, True], is equal to False in [False, True], which is True (False is contained in the list).


回答 7

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

To clarify on some of the other answers, adding parentheses after a unary operator does not change its precedence. not(True) does not make not bind more tightly to True. It’s just a redundant set of parentheses around True. It’s much the same as (True) in [True, False]. The parentheses don’t do anything. If you want the binding to be more tight, you have to put the parentheses around the whole expression, meaning both the operator and the operand, i.e., (not True) in [True, False].

To see this another way, consider

>>> -2**2
-4

** binds more tightly than -, which is why you get the negative of two squared, not the square of negative two (which would be positive four).

What if you did want the square of negative two? Obviously, you’d add parentheses:

>>> (-2)**2
4

However, it’s not reasonable to expect the following to give 4

>>> -(2)**2
-4

because -(2) is the same as -2. The parentheses do absolutely nothing. not(True) is exactly the same.