Pythonリストの深度コピーと浅いコピー例の詳細


一、深くコピーします。浅いコピーです。
リストはPythonで持参したデータ構造です。リストを使う時、コピーは避けられません。リストの深度コピーと浅いコピーについて簡単に説明します。
まずコードを見ます

l1 = [5, 4, 3, 2, 1]
#           l1   
l2 = l1
l3 = l1[:]
print(l1) # [5, 4, 3, 2, 1]
print(l2) # [5, 4, 3, 2, 1]
print(l3) # [5, 4, 3, 2, 1]
 
#  l1
l1[0] = 9
print(l1) # [9, 4, 3, 2, 1]
print(l2) # [9, 4, 3, 2, 1]
print(l3) # [5, 4, 3, 2, 1]
l 1の最初の要素を修正した後、l 2の最初の要素は変化しますが、l 3は変化していません。Pythonは関数id()を内蔵して要素の住所を返すことができます。この関数を使って3つのリストの住所を見てみます。

print(id(l1)) # 2927957162504
print(id(l2)) # 2927957162504
print(id(l3)) # 2927923243528
その結果、l 1とl 2のアドレスは同じです。つまり、l 1とl 2は同じメモリ領域を指しています。l 2=l 1で操作すると、l 1とl 2は同じメモリアドレスを指す「ポインタ」になります。つまり、この操作はl 1の別名を取っています。l 2はl 1の参照とも言えます。一枚の図で説明します。

l 1を修正します。つまり、l 2を修正します。

次にl 3を作成する過程を見ます。l 3 = l 1[:]は、l 1をスライスし、スライスしたリストをl 3が指すメモリ領域にコピーするもので、同様に図を参照する。

つまり、l 1とl 3は異なるメモリ領域を指しているので、l 1を修正すると、l 3に影響がありません。

簡単に言えば、l 2のように、コピーされたオブジェクトは元のオブジェクトのアドレスと同じで、浅いコピーのために、l 3のように、新しいメモリ空間を割り当ててオリジナルのコンテンツをコピーする場合、コピーされたオブジェクトは元のオブジェクトのアドレスとは違って、深くコピーされます。
二、リスト内の要素の浅いコピーをコピーします。
リストのすべての要素をコピーするときに、浅いコピーを行います。
比較的面白いものを見てコードを見ます。

l1 = [1,2,3,[1,3]]
l2 = l1[:]
l1[3][1] = 9
print(l1) # [1, 2, 3, [1, 9]]
print(l2) # [1, 2, 3, [1, 9]]
前の理解では、l 1の要素を修正したら、l 2は変わらないはずですが、結果は予想していた結果とは大きく違っています。そこで、私達はl 2の深複製が何をコピーしたのかを考えなければなりません。実際のリストは、「ポインタ」として理解できます。l 1[3]はリスト要素です。l 2[3]もリスト要素です。以下のコードを実行します。

print(id(l2[3])) # 2014816956232
print(id(l1[3])) # 2014816956232
私達はl 1[3]とl 2[3]の指し示す住所が同じであることを発見しました。つまり実行中です。 l 2=l 1[:]をコピーした場合、l 1[3]を修正することは修正l 2[3]に相当するので、上記の結果が現れます。これはさらに、リストとはメモリ領域を指す「ポインタ」です。リストl 2は、深くl 1をコピーしたと言ってもいいですが、リスト内の各要素をコピーする場合は、浅いコピーを行いますか?答えは明らかだ。

l 1[3]の要素を変更します。

三、copy()とdeepcopy()
copyモジュールはオブジェクトのコピー操作を実現するのに役立ちます。
他のコピーリストを列挙する方式:

l4 = l1 * 1
print(id(l4)) # 2927957916296
l5 = list(l1)
print(id(l5)) # 2927957767816
import copy
l6 = copy.copy(l1)
print(id(l6)) # 2927956854024
l7 = copy.deepcopy(l1)
print(id(l7)) # 2927958503368
これらのコピーによって得られた新しいオブジェクトは元のオブジェクトのアドレスとは違っています。文字どおりに浅いコピー、deepcopyを深くコピーしていません。copy()とdeepcopy()はどのような違いがありますか?コードを見続けます。

list1 = [1,2,3,[1,3]]
list2 = list1[:]
list3 = copy.copy(list1)
list4 = copy.deepcopy(list1)
list1[3][0] = 9
print(list1) # [1, 2, 3, [9, 3]]
print(list2) # [1, 2, 3, [9, 3]]
print(list3) # [1, 2, 3, [9, 3]]
print(list4) # [1, 2, 3, [1, 3]]
print(id(list1[3])) # 2927923172616
print(id(list2[3])) # 2927923172616
print(id(list3[3])) # 2927923172616
print(id(list4[3])) # 2927967190728
copy()と前述のコピーでは本質的な違いはなく、リスト内の各要素をコピーする際には浅いコピーを行い、deepcopy()は複製リストの各要素の時には、深いコピーを行うことができます。


締め括りをつける
ここでPythonリストの深度コピーと浅いコピーについての記事を紹介します。もっと関連するPythonリストの深度コピーと浅いコピーの内容は以前の文章を検索してください。または下記の関連記事を引き続きご覧ください。これからもよろしくお願いします。