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

回答:


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。1つ目は、関数呼び出しのように見えます。これが混乱の原因です。not関数の場合は、にnot(True) in ...なる可能性はありませんnot ((True) in ...)。あなたはそれが演算子であることを知っている必要があります(またはあなたはこのような状況に終わる)ので、関数としてそれを偽装するのではなく、演算子のように書くべきです。
Ben

7
また、読者の利益のために優先順位を示すためにスペースを使用する場合は、最初に正しいことを確認してください。書くのはおそらく大丈夫ですが、書くa + b*c + dのはとても悪いa+b * c+dです。だからnot(True)、その対策によっても悪いです。
スティーブジェソップ2015

32
実際には、決して書きませんnot TrueFalse代わりに書いてください。
Darkhogg

10
おそらくあなたが書くことではないでしょう実際の生活の中でnot True、あなたのような何かを書くことにしたいnot myfunc(x,y,z)ところmyfunc、いくつかの機能が戻っていることであるTrueかをFalse
Nate CK、

3
@ BenC.R.Leggieroそれは私が元の答えでやったことであり、他の人が修正しました。現在のバージョンは私にとっては十分に明確です。重要な問題が指摘されているので、余分な括弧がないと理解しにくいとは思いません。残りの部分を理解することは、プログラマーの基本的なスキルです。
Yu Hao

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

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        

13
そこの男は常にあるdisが、それは実際にすることを示しているので、これは非常に貴重な答えであるnot in使用されている
jamylak

21
バイトコードは、CPythonインタープリターの実装の詳細です。これは、Pythonの質問に対するCPythonの回答です。実際、言語リファレンスから直接回答する方が適切です。
2015

5
@wimバイトコードの実装は実際の逆アセンブリほど重要ではないと主張します。他の実装は機能的に同一のものを生成することが保証されているため、1つの逆アセンブリを理解すると、低レベルの「方法」ではなく「理由」を理解するのに十分な洞察が得られます。
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つのロール(precedenceまたはchaining)を使用することに注意してください。この場合、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 TrueそれですFalse

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

また、これは、オペランドに続くメンバーシップテストとアイデンティティテスト操作を含むすべての比較にも当てはまります。

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

例:

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

もう1つの有名な例は、数値範囲です。

7<x<20

これは次と同じです:

7<x and x<20   

6

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

True in [False, True]TrueTrueリストに含まれる要素と同様にを返します。

したがって、上記の式の結果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)の2乗ではなく、2の2乗の負が得られます。

負の2の2乗が必要な場合はどうでしょうか。明らかに、括弧を追加します:

>>> (-2)**2
4

ただし、次のことを期待するのは合理的ではありません 4

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

理由-(2)と同じです-2。括弧はまったく何もしません。not(True)まったく同じです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.