web-dev-qa-db-ja.com

Pythonの2つの変数は同じIDを持ちますが、リストやタプルはありません

Python=の2つの変数は同じidを持っています:

a = 10
b = 10
a is b
>>> True

2つのlistsを取る場合:

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

このリンク によると、Senderleは、不変オブジェクト参照は同じIDを持ち、リストのような可変オブジェクトは異なるIDを持つと回答しました。

だから今彼の答えによると、タプルは同じIDを持つ必要があります-意味:

a = (1, 2, 3)
b = (1, 2, 3)
a is b
>>> False

理想的には、タプルは可変ではないため、Trueを返す必要がありますが、Falseを返します!

説明は何ですか?

43
Ram Vallury

不変オブジェクトには同じidがありません。実際、これは個別に定義するオブジェクトの種類には当てはまりません。一般的に、Pythonでオブジェクトを定義するたびに、新しいIDで新しいオブジェクトを作成します。

ただし、最適化のため(ほとんど)、小さな整数(-5〜256)と小さな文字列(特別な長さ(通常20文字未満)のインターンされた文字列)には、シングルトンで同じidを持ついくつかの例外があります(実際には、複数のポインターを持つ1つのオブジェクト)。次のようにこの事実を確認できます。

>>> 30 is 20 + 10
True
>>> 
>>> 300 is 200 + 100
False
>>> 'aa' * 2 is 'a' * 4
True
>>> 'aa' * 20 is 'a' * 40
False

カスタムオブジェクトの場合:

>>> class A:
...    pass
... 
>>> A() is A() # Every time you create an instance you'll have a new instance with new identity
False

また、is演算子は値ではなくオブジェクトのIDをチェックすることに注意してください。値を確認する場合は、==を使用する必要があります。

>>> 300 == 3*100
True

そして、任意のサイズで2つの同じタプルを定義すると、タプル(他のタイプ)にはそのようなルールがないため、独自のIDを取得します。

>>> a = (1,)
>>> b = (1,)
>>>
>>> a is b
False

そして、シングルトン整数とインターンされた文字列の事実は、可変および不変オブジェクト内で定義した場合でも真実であることに注意してください。

>>> a = (100, 700, 400)
>>>
>>> b = (100, 700, 400)
>>>
>>> a[0] is b[0]
True
>>> a[1] is b[1]
False
60
Kasrâmvd

不変!=同じオブジェクト。*

不変オブジェクトは、状態を変更できないオブジェクトにすぎません; それだけです。 新しいオブジェクトが作成されると、新しいアドレスが割り当てられますアドレスがisと等しい場合、Falseを返します。

事実 1 is 1または"a" is "a"Trueを返します- 整数キャッシング と文字列 interning によるPython ;対象のオブジェクトが可変/不変であることとは関係ありません。


*空の不変オブジェクト 同じオブジェクトを参照してください およびisnessはtrueを返しますが、これは特別な実装固有のケースです。

このコードを見てください:

>>> a = (1, 2, 3)
>>> b = (1, 2, 3)
>>> c = a
>>> id(a)
178153080L
>>> id(b)
178098040L
>>> id(c)
178153080L

理由を理解するためにa is cTrueとして評価されますが、a is b yields FalseOnline Python Tutor で上記のスニペットを段階的に実行することを強くお勧めします。メモリ内のオブジェクトは、この問題に対するより深い洞察を提供します(スクリーンショットを添付します)。

enter image description here

16
Tonechas

以下のコードを確認してください。tupilsaおよびbは古い参照を保持しています(ID)古い値を割り当てたときに戻ります。 (ただし、これはリストが可変であるため、リストの場合ではありません)

最初はabは同じ値((1,2)) 、しかしそれらは異なるIDを持っています。値を変更した後、値(1,2)をaおよびb、彼らは彼ら自身の同じID(それぞれ88264264と88283400)を参照しています。

>>> a = (1,2)
>>> b = (1,2)
>>> a , b
((1, 2), (1, 2))
>>> id(a)
88264264
>>> id(b)
88283400
>>> a = (3,4)
>>> b = (3,4)
>>> id(a)
88280008
>>> id(b)
88264328
>>> a = (1,2)
>>> b = (1,2)
>>> id(a)
88264264
>>> id(b)
88283400
>>> a , b
((1, 2), (1, 2))
>>> id(a) , id(b)
(88264264, 88283400)
>>> 

**リンクを確認してください 同じ値を割り当てたときにタプルが同じIDを取得しないのはなぜですか? これを読んだ後も。別のケースもここで説明されています。

0
AKSHAY KUMAR