Pythonの「xがNoneでない場合」または「xがNoneでない場合」?


746

私は常にif not x is Noneバージョンをより明確にすることを考えていましたが、GoogleのスタイルガイドPEP-8はどちらもを使用していますif x is not None。マイナーなパフォーマンスの違いはありますか(私はそうではないと思います)、1つが実際には適合しない(私のコンベンションで他が明らかに勝者になる)ケースはありますか?*

*私は単にではなく、任意のシングルトンを指しNoneます。

... Noneのようなシングルトンを比較します。使用するかしないか。


8
is notそれ自体が演算子です。のように!=。ご希望の場合はnot x is None、あなたのも好むはずですnot a == b以上a != b
Tomasz Gandor 2018年

@TomaszGandor私はもはやこの意見を持っていませんnot x is None(ここでの回答で私を納得させました)。しかし、それはnot a == bPythonで推奨されるスタイルa != bです。
orokusaki

4
@orokusakiはnot a == b本当に望ましいスタイルですか?私はそれがそのように行われるのを見たことがありません!=
マイク

2
Pythonの可読性数の@orokusaki一人のオペレータを使用することが好ましいスタイルですので、!=代わりに2つの演算子not==
Jeyekomon、

回答:


995

同じバイトコードにコンパイルされるため、パフォーマンスの違いはありません。

Python 2.6.2 (r262:71600, Apr 15 2009, 07:20:39)
>>> import dis
>>> def f(x):
...    return x is not None
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE
>>> def g(x):
...   return not x is None
...
>>> dis.dis(g)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE

文体的に、私は避けようとしnot x is yます。コンパイラは常にそれをとして扱いますがnot (x is y)、人間の読者は構成をと誤解する可能性があり(not x) is yます。私が書いた場合x is not y、あいまいさはありません。


103
同じ人間の読者がそうだと思ったのでなければx is (not y)。しかし、私はあなたの他の理由であなたに同意する傾向があります。
Etaoin、

24
:「なしaとbがNoneでない場合は、」対:さらに「なしとbがNoneでない場合は、」このような状況ではあまり曖昧さ「ではない」
ゴードン・リグリー

45
演算子は "aint"である必要があります
Bean

217

GoogleとPythonの両方のスタイルガイドがベストプラクティスです。

if x is not None:
    # Do something about x

を使用not xすると、望ましくない結果が生じる可能性があります。

下記参照:

>>> x = 1
>>> not x
False
>>> x = [1]
>>> not x
False
>>> x = 0
>>> not x
True
>>> x = [0]         # You don't want to fall in this one.
>>> not x
False

どのリテラルがPythonで評価されるTrueFalse、またはPythonで評価されるかに興味があるかもしれません。


以下のコメント用に編集:

私はさらにいくつかのテストを行いました。最初にnot x is None否定せずx、次にと比較しませんNone。実際、そのようisに使用すると、演算子の優先順位が高くなるようです。

>>> x
[0]
>>> not x is None
True
>>> not (x is None)
True
>>> (not x) is None
False

したがって、not x is None正直なところ、回避するのが最善です。


さらに編集:

私はもっと多くのテストをしただけで、ブクゾールのコメントが正しいことを確認できます。(少なくとも、それ以外の場合は証明できませんでした。)

これif x is not Noneは、正確な結果がであることを意味しif not x is Noneます。私は修正された立場です。ありがとうbukzor。

ただし、私の答えはまだ残っています。従来のを使用してくださいif x is not None:]


131

コードは、最初はプログラマーが理解できるように記述し、次にコンパイラーまたはインタープリターを理解できるように記述します。「is not」構文は「not is」よりも英語に似ています。


33

Python if x is not Noneまたはif not x is None

TLDR:バイトコードコンパイラーは両方を解析しx is not Noneて、読みやすくしますif x is not None

読みやすさ

Pythonを使用しているのは、パフォーマンスよりも人間の可読性、使いやすさ、プログラミングのさまざまなパラダイムの正確さなどを重視しているためです。

Pythonは、特にこのコンテキストにおいて、可読性を最適化します。

バイトコードの解析とコンパイル

not より弱く結合よりはis、とてもここには論理的な違いはありません。ドキュメントを参照してください:

演算子isis notオブジェクトIDのテスト:x is yxとyが同じオブジェクトである場合にのみtrueです。x is not y逆の真理値を生成します。

is not具体的には、Pythonの中に設けられている文法言語の可読性の向上など。

comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'

そして、それは文法の単一要素でもあります。

もちろん、同じようには解析されません。

>>> import ast
>>> ast.dump(ast.parse('x is not None').body[0].value)
"Compare(left=Name(id='x', ctx=Load()), ops=[IsNot()], comparators=[Name(id='None', ctx=Load())])"
>>> ast.dump(ast.parse('not x is None').body[0].value)
"UnaryOp(op=Not(), operand=Compare(left=Name(id='x', ctx=Load()), ops=[Is()], comparators=[Name(id='None', ctx=Load())]))"

ただし、バイトコンパイラは実際にnot ... isis not次のように変換します。

>>> import dis
>>> dis.dis(lambda x, y: x is not y)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE
>>> dis.dis(lambda x, y: not x is y)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE

したがって、読みやすさと意図された言語の使用のために、を使用してくださいis not

使用しないのは賢明ではありません


notバインドはよりも弱いためis、ここでは論理的な違いはありません」-Pythonが保持する論理的および代数的アイデンティティを強制する必要がないことを除きます((1 + 2)*3と同じように評価する固有の理由はありません1*3 + 2*3)。ここではどうやらPythonが不正行為をして最適化を進めUNARY_NOTているようです。
Alexey

30

答えは、人々が作っているよりも簡単です。

どちらの方法にも技術的な利点はありません。「xはyではありません」が他の誰もが使用するものであり、これが明らかに勝者です。「英語に似ている」かどうかは関係ありません。誰もがそれを使用します。つまり、Pythonのすべてのユーザー(言語がPythonのように見えない中国のユーザーであっても)は一目でそれを理解します。少し一般的でない構文では、解析に余分な脳のサイクルが2、3回かかります。

少なくともこの分野では、違いをもたらすためだけに違いはありません。


11

is notオペレータは、結果否定より好ましいis文体の理由のために。「if x is not None:」は英語のように読みますが、「if not x is None:」は演算子の優先順位を理解する必要があり、英語のようには読みません。

パフォーマンスの違いがある場合、私のお金は当てis notになりますが、これはほぼ確実に、その手法を選択する決定の動機ではありません。それは明らかに実装依存です。isはオーバーライド可能ではないため、いずれにせよ、区別を簡単に最適化できるはずです。


9

個人的には

if not (x is None):

これは、Python構文の専門家でなくても、すべてのプログラマーによって曖昧さなく即座に理解されます。


5
私はそれに同意する公正な議論ですが、私は慣用的なスタイルに従うという議論がより強いと信じています。
2016年

2

if not x is None他のプログラミング言語に似ていif x is not Noneますが、私には間違いなく明確に聞こえます(英語では文法的に正しい)。

とはいえ、私にとっては好みのように思えます。


0

可読性の高いx is not y コードを生成するために、演算子の優先順位を処理するコードを最終的にどのように記述するかを考えるよりも、可読性の高い形式を好みます。

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