web-dev-qa-db-ja.com

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

どうして?

469
Texom512

演算子の優先順位 2.x3.xnotの優先順位はinの優先順位よりも低くなります。それでそれは同等です:

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

これはあなたが欲しいものです:

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

@ Benが指摘するように、not(True)は絶対に書かないことをお勧めします。not Trueを推奨します。前者は関数呼び出しのように見えますが、notは演算子であり関数ではありません。

719
Yu Hao

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

2番目のケースは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        
73
Roshan Mathews

演算子の優先順位innotよりも緊密にバインドされるため、式はnot((True) in [False, True])と同等です。

35
mooiamaduck

これはすべて 演算子の優先順位 についてです(innotよりも強力です)。しかし、適切な場所に括弧を追加することで簡単に修正できます。

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

書き込み:

not(True) in [False, True]

と同じです:

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

これはTrueがリストの中にあるかどうかを調べ、結果の "not"を返します。

33
alfasin

Falsenot True in [False, True]にあるため、Trueを返す[False, True]として評価されます。

試してみると

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

期待通りの結果が得られます。

14
user3636636

notの優先順位がinより低いと述べた他の答えと並んで、実際にはあなたの文は以下と同等です。

not (True in [False, True])

ただし、自分の状態を他の状態と区別しない場合、pythonはそれを分離するために2つの役割(precedenceまたはchaining)を使用します。この場合は、pythonが優先されます。また、条件を分離したい場合は、オブジェクトや値だけでなく、すべての条件を括弧で囲む必要があります。

(not True) in [False, True]

しかし、すでに述べたように、連鎖という演算子に対するpythonによる変更がもう1つあります。

Python のドキュメントに基づく

比較、メンバシップテスト、および同一性テストはすべて同じ優先順位を持ち、比較セクションで説明されているように左から右への連鎖機能を持っていることに注意してください。

たとえば、次の文の結果はFalseです。

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

なぜなら、pythonは次のように文を連鎖させるからです。

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

これは正確にFalse and True、つまりFalseです。

中央のオブジェクトは、2つの操作と他のオブジェクトとの間で共有されると想定できます(この場合はFalse)。

また、メンバーシップテストやIDテストの操作(オペランドに続く)を含むすべての比較についても同じことが言えます。

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

例:

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

もう一つの有名な例は数の範囲です:

7<x<20

これは以下と同じです。

7<x and x<20   
13
Kasrâmvd

他の答えのいくつかを明確にするために、括弧afterを単項演算子に追加しても優先順位は変わりません。 not(True)は、notTrueにさらに厳密にバインドさせるわけではありません。それはTrueを囲む単なる冗長な括弧です。 (True) in [True, False]とほとんど同じです。括弧は何もしません。バインディングをより厳密にしたい場合は、式全体を括弧で囲む必要があります。つまり、演算子とオペランドの両方、つまり(not True) in [True, False]を意味します。

これを別の方法で見るには、

>>> -2**2
-4

**-よりも緊密にバインドされます。これが、負の2の平方ではなく、2の平方の負の平方を得る理由です。

あなたが負の2の二乗を求めたとしたら?明らかに、括弧を追加します。

>>> (-2)**2
4

しかし、以下が4を与えると期待するのは合理的ではありません。

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

-(2)-2と同じなので。括弧は絶対に何もしません。 not(True)はまったく同じです。

6
asmeurer

コレクションの包含チェック操作として見てみましょう:[False, True]はいくつかの要素を含むリストです。

Trueはリストに含まれる要素なので、式True in [False, True]Trueを返します。

したがって、not True in [False, True]は、上記の式の「ブール値の反対」、notの結果を示します(innot演算子よりも優先順位が高いため、優先順位を維持するための括弧なし)。したがって、not TrueFalseになります。

一方、(not True) in [False, True]False in [False, True]と等しく、これはTrueです(Falseはリストに含まれています)。

6

ここ は演​​算子の優先順位に関するドキュメントです

in binds tighter than not

そうすることは目的に役立ちます

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