あなたはis
またはid
を使用してテストが真のコピーが行われているかどうかの誤解を招くことができることを知っている必要がありimmutablesを含む文字列、整数、タプルなどのオブジェクトは不変でinternedです。
簡単インターン文字列の例を理解して考えてみましょう:
>>> l1=['one']
>>> l2=['one']
>>> l1 is l2
False
>>> l1[0] is l2[0]
True
は今l1
の簡易コピーを作成し、不変の文字列をテストします。
>>> l3=l1[:]
>>> l3 is l1
False
>>> l3[0] is l1[0]
True
今すぐl1[0]
に含まれる文字列のコピーを作成:
>>> s1=l1[0][:]
>>> s1
'one'
>>> s1 is l1[0] is l2[0] is l3[0]
True # they are all the same object
T RYすべての要素をコピーする必要がありますdeepcopy:(彼らは同じid
を持っている)いずれの場合においても
>>> from copy import deepcopy
>>> l4=deepcopy(l1)
>>> l4[0] is l1[0]
True
は、文字列'one'
は不変の文字列のPythonの内部キャッシュに抑留されているとis
は、それらが同じであることが表示されます。これは、実装されているものと実行されたときの実装とバージョンに依存するため、依存することはできません。これは、メモリとパフォーマンスを大幅に向上させることができます。
あなたは即座に抑留されない例に強制することができます
>>> s2=''.join(c for c in 'one')
>>> s2==l1[0]
True
>>> s2 is l1[0]
False
をそしてあなたが見つかった場合、その文字列がキャッシュされたオブジェクトを参照させるためにはPython intern functionを使用することができます。
>>> l1[0] is s2
False
>>> s2=intern(s2)
>>> l1[0] is s2
True
同じ
immutablesのタプルに適用されます。
>>> t1=('one','two')
>>> t2=t1[:]
>>> t1 is t2
True
>>> t3=deepcopy(t1)
>>> t3 is t2 is t1
True
アン(整数のような)immutablesのD変更可能なリストは、リストのメンバーが埋葬持つことができます。
>>> li1=[1,2,3]
>>> li2=deepcopy(li1)
>>> li2 == li1
True
>>> li2 is li1
False
>>> li1[0] is li2[0]
True
ですから、あなたが知っているPythonのオペレーションを使用することが最終的な結果が、何かをコピーしますインターン不変オブジェクトへの別の参照です。 is
テストは、アイテムが変更可能な場合に作成されるコピーの慎重なテストにすぎません。
なぜ私は異なるIDを取得しているのですか? – user2528042
@ user2528042:*外部リストオブジェクト*は同じではないためです。 –
@ user2528042元のリスト*が新しいオブジェクトにコピーされる*ため。内のすべての要素がコピーされないので、リストに変更可能なオブジェクトが含まれていれば(intsは変更不可能です)、そのオブジェクトを変更すると、元のオブジェクトとコピーされたリストの両方が同じオブジェクトへの参照のコピーを持つため変更されます。 – poke