(私は例であまりにも多くの時間を無駄にし、@Konrad Rudolph が私を答えに打ち負かしました。私は基本的に彼と同じことを言っています)
Python は内部で C ポインターの割り当てと同等の処理を行っており、L1 はメモリ内のリストのアドレスを保持し、L2 は同じアドレスをコピーしただけです。
is
演算子を使用するだけで、コードをチェックインできます。
>>> L1 is L2
True
ただし、スライスを使用する場合は、元のリストとは異なるため、新しいリストを作成する必要がありますが、すべてをコピーするのではなく、内部のオブジェクトへの参照をコピーするだけです。
より複雑な例を次に示します。
>>> L1 = [1, [2, 3], 4]
>>> L2 = L1
>>> L2
[1, [2, 3], 4]
>>> L1[1] is L2[1]
True
わかりましたので、L1
内部にリストを含むリストを保持します。これを辞書、文字列、またはその他の python オブジェクトに置き換えることができます。リスト内のリストに対してis
演算子が返されることに注意してください。True
次に、スライスのトリックを行う場合:
>>> L3 = L1[:2]
>>> L3
[1, [2, 3]]
>>> L3 is L1
False
>>> L3[1] is L2[1]
True
外部リストは変更されていますが、内部のオブジェクトは同じままです。これは、浅いコピーとして知られています。実際、リスト内のリストに新しいアイテムを追加する場合、同じルールが引き続き適用されます。
>>> L3[1].append(9)
>>> L3
[1, [2, 3, 9]]
>>> L1
[1, [2, 3, 9], 4]
(追加された 9 に注意してください) と の両方の内部のリストL1
がL3
変更されています。
対照的に、deepcopy
浅いコピーが望ましくない場合に行うことができます。
>>> from copy import deepcopy
>>> L3 = deepcopy(L1)
>>> L3
[1, [2, 3, 9], 4]
>>> L3 is L1
False