web-dev-qa-db-ja.com

ifループ:「x not in」と「not x in」

私はこれらの両方が同じように機能することに気づきました:

if x not in listおよびif not x in list

場合によっては、2つの間に何らかの違いがありますか?両方を持っている理由はありますか、それとも単に一部の人々がどちらか一方を書くほうが自然であるという理由だけですか?

他の人のコードで見られる可能性が高いのはどれですか?

54
avacariu

明確に確認できるように、2つの形式は同じバイトコードを作成します。

_>>> import dis
>>> dis.dis(compile('if x not in d: pass', '', 'exec'))
  1           0 LOAD_NAME                0 (x)
              3 LOAD_NAME                1 (d)
              6 COMPARE_OP               7 (not in)
              9 JUMP_IF_FALSE            4 (to 16)
             12 POP_TOP             
             13 JUMP_FORWARD             1 (to 17)
        >>   16 POP_TOP             
        >>   17 LOAD_CONST               0 (None)
             20 RETURN_VALUE        
>>> dis.dis(compile('if not x in d: pass', '', 'exec'))
  1           0 LOAD_NAME                0 (x)
              3 LOAD_NAME                1 (d)
              6 COMPARE_OP               7 (not in)
              9 JUMP_IF_FALSE            4 (to 16)
             12 POP_TOP             
             13 JUMP_FORWARD             1 (to 17)
        >>   16 POP_TOP             
        >>   17 LOAD_CONST               0 (None)
             20 RETURN_VALUE        
_

明らかにそれらは意味的に同一です。

スタイルの問題として、 PEP 8 はこの問題について言及していません。

個人的には、_if x not in y_形式を強く推奨します。これにより、_not in_が単一の演算子andであることがすぐにわかります "英語のように読みます。」 _if not x in y_は、一部の読者をif (not x) in yを意味するものと誤解させ、英語のように少し読みにくくし、補償する利点がまったくありません。

67
Alex Martelli
>>> dis.dis(lambda: a not in b)
1           0 LOAD_GLOBAL              0 (a)
          3 LOAD_GLOBAL              1 (b)
          6 COMPARE_OP               7 (not in)
          9 RETURN_VALUE      

>>> dis.dis(lambda: not a in b)
1           0 LOAD_GLOBAL              0 (a)
          3 LOAD_GLOBAL              1 (b)
          6 COMPARE_OP               7 (not in)
          9 RETURN_VALUE  

「not a in b」を実行する場合は、(not in)に変換する必要があります

したがって、正しい方法は「a not b」です。

6
killown

not x in Lばかげているので、明示的に禁止されていません。 x not in Lは読みやすいので、(同じバイトコードにコンパイルされますが)明示的に許可されています。

x not in Lは、誰もが使用するものです。

4
habnabit

a not in bnot in演算子を使用していますが、not a in bin演算子を使用して結果を否定しています。ただし、not in演算子はnot a in bと同じものを返すように定義されているため、まったく同じことを行います。 ドキュメント から:

演算子inおよびnot inは、コレクションのメンバーシップをテストします。 xがコレクションsのメンバーである場合、x in sはtrueと評価され、そうでない場合はfalseと評価されます。 x not in sx in sの否定を返します。

同様に、a is not bnot a is bがあります。

追加の構文が追加されたのは、人間が自然に読みやすくなるためです。

3
Mark Byers

それは個人的な好みです。 if x != 3if not x == 3を比較することもできます。これまでに示した2つの式に違いはありません。

1
Ned Batchelder