629

私のGoogle-fuは私に失敗しました。

Pythonでは、同等性に関する次の2つのテストは同等ですか?

n = 5
# Test one.
if n == 5:
    print 'Yay!'

# Test two.
if n is 5:
    print 'Yay!'

これは、インスタンスを比較するオブジェクト(たとえば)にも当てはまりますlistか?

さて、この種の答えは私の質問です:

L = []
L.append(1)
if L == [1]:
    print 'Yay!'
# Holds true, but...

if L is [1]:
    print 'Yay!'
# Doesn't.

では、テストは、それらが同じオブジェクトであるかどうかを確認するために==どこでテストするかを評価しますか?is

4

14 に答える 14

1060

is変数によって参照されるオブジェクトが等しいTrue場合、2 つの変数が (メモリ内の) 同じオブジェクトを指している場合に返されます。==

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True

# Make a new copy of list `a` via the slice operator, 
# and assign it to variable `b`
>>> b = a[:] 
>>> b is a
False
>>> b == a
True

あなたの場合、2 番目のテストは、Python が実装の詳細である小さな整数オブジェクトをキャッシュするためにのみ機能します。より大きな整数の場合、これは機能しません。

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True

同じことが文字列リテラルにも当てはまります。

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

こちらの質問もご覧ください。

于 2008-09-25T12:32:37.473 に答える
362

==またはをいつ使用するかを示す簡単な経験則がありますis

  • ==値の等価性のためです。2 つのオブジェクトが同じ値を持っているかどうかを知りたい場合に使用します。
  • is参考程度です。2 つの参照が同じオブジェクトを参照しているかどうかを知りたい場合に使用します。

一般に、何かを単純型と比較するときは、通常、値が等しいかどうかをチェックしているため、 を使用する必要があります==。たとえば、この例の意図は、xが文字通り 2 と同じオブジェクトを参照している==かどうかではなく、2 () に等しい値を持っているかどうかを確認することです。x


他に注意すべき点: CPython 参照実装の仕組みにより、is整数の参照の等価性を誤って比較すると、予期しない一貫性のない結果が得られます。

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False

これはほぼ予想どおりです。同じ値ab持ちますが、異なるエンティティです。しかし、これはどうですか?

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True

これは以前の結果と一致しません。何が起きてる?Python のリファレンス実装は、パフォーマンス上の理由から、-5..256 の範囲の整数オブジェクトをシングルトン インスタンスとしてキャッシュします。これを示す例を次に示します。

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
... 
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

これは、使用しないもう 1 つの明らかな理由isです。値の等価性のために誤って使用している場合、動作は実装に任されています。

于 2009-07-06T06:22:52.760 に答える
43

==値が等しいisかどうかを判断し、それらがまったく同じオブジェクトであるかどうかを判断します。

于 2008-09-25T12:31:12.533 に答える
21

それらは完全に異なります。 isはオブジェクトの同一性を==チェックし、等価性 (2 つのオペランドの型に依存する概念) をチェックします。

is" " が小さい整数 (たとえば 5 == 4+1) で正しく機能するように見えるのは、幸運な偶然です。これは、CPython が範囲 (-5 から 256) の整数を singleton にすることで、そのストレージを最適化するためです。この動作は完全に実装に依存しており、あらゆる種類のマイナーな変換操作の下で保持されることは保証されていません。

たとえば、Python 3.5 も短い文字列のシングルトンを作成しますが、それらをスライスするとこの動作が妨げられます。

>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False
于 2008-09-25T17:15:38.323 に答える
12

https://docs.python.org/library/stdtypes.html#comparisons

is同一性の ==テスト 等しいかどうかのテスト

各 (小さい) 整数値は単一の値にマップされるため、すべての 3 は同一で等しいです。これは実装の詳細であり、言語仕様の一部ではありません

于 2008-09-25T12:31:57.757 に答える
7

あなたの答えは正しいです。オペレーターはis、2 つのオブジェクトの ID を比較します。演算子は==、2 つのオブジェクトの値を比較します。

オブジェクトの ID は、一度作成されると変更されることはありません。メモリ内のオブジェクトのアドレスと考えることができます。

__cmp__メソッドまたは のような豊富な比較メソッドを定義することにより、オブジェクト値の比較動作を制御できます__eq__

于 2008-09-25T12:34:18.920 に答える
5

スタック オーバーフロー質問を見てください。

要するに、 " is" は、それらが単に等しいだけでなく、同じオブジェクトであるかどうかをチェックするということです (256 未満の数値は特殊なケースです)。

于 2009-07-06T06:20:00.237 に答える
3

John Feminella が言ったように、目的は値を比較することなので、ほとんどの場合 == と != を使用します。残りの時間に何をするかを分類したいと思います。

NoneType のインスタンスは 1 つだけです。つまり、None はシングルトンです。したがってfoo == Nonefoo is None同じ意味です。ただし、isテストはより高速であり、Pythonic の規則ではfoo is None.

イントロスペクションを行ったり、ガベージ コレクションをいじったり、カスタムビルドの文字列インターン ガジェットが機能しているかどうかを確認したりしている場合は、おそらく is の使用例がfooありbarます。

True と False も (現在) シングルトンですがfoo == True、 のユースケースも のユースケースもありませんfoo is True

于 2009-07-06T08:50:52.663 に答える
3

彼らのほとんどは、すでにその点に答えています。追加のメモとして(文書化されたソースからではなく、私の理解と実験に基づいて)、ステートメント

== 変数によって参照されるオブジェクトが等しい場合

上記の回答から、次のように読む必要があります

== 変数によって参照されるオブジェクトが等しく、同じタイプ/クラスに属するオブジェクトの場合

. 以下のテストに基づいて、この結論に達しました。

list1 = [1,2,3,4]
tuple1 = (1,2,3,4)

print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))

print(list1 == tuple1)
print(list1 is tuple1)

ここでは、リストとタプルの内容は同じですが、型/クラスが異なります。

于 2018-03-07T08:05:20.210 に答える