リストの対角要素を1に設定しようとしましたが、すべての要素が1として割り当てられました。
a = [[0]*3]*3
print(a) #[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
for i in range(len(a)):
a[i][i] = 1
print(a) #[[1, 1, 1], [1, 1, 1], [1, 1, 1]
ただし、次の方法で問題なく動作します。
a = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
print(a) #[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
for i in range(len(a)):
a[i][i] = 1
print(a) #[[1, 0, 0], [0, 1, 0], [0, 0, 1]]
なぜこれが起こっているのか考えはありますか?
浅いコピーと深いコピー(またはこの場合は浅いコピーと明示的な割り当て)の違いを理解すれば、この動作を理解するのは非常に簡単です。
公式ドキュメントから-
その理由は、*を使用してリストを複製してもコピーは作成されず、既存のオブジェクトへの参照のみが作成されるためです。* 3は、長さ2の同じリストへの3つの参照を含むリストを作成します。
2番目のケースでは、リストのリスト内の各要素を明示的に割り当てています。一方を変更しても、もう一方には影響しません。
#EXPLICIT ASSIGNMENT!
a = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
for i in range(len(a)):
a[i][i] = 1
しかし、最初のケースでは、*
オペレータは、浅いコピー作成の[0]
(およびその後の浅いコピー[0,0,0]
も同様)。
#REPETITION OPERATOR
a = [[0]*3]*3
for i in range(len(a)):
a[i][i] = 1
これは、ある理由あなたは、この動作を参照してください理由。深いコピー(または明示的な割り当て2番目の場合のように)は、まず新しいコレクションオブジェクトを作成し、次に再帰的に子オブジェクトのコピーを移入元で見つかりました。ディープコピーの場合、オブジェクトのコピーが他のオブジェクトにコピーされます。これは、オブジェクトのコピーに加えられた変更が元のオブジェクトに反映されないことを意味します。
最初のケースでは、浅いコピーを使用して新しいコレクションオブジェクトを作成し、元のオブジェクトにある子オブジェクトへの参照をそのオブジェクトに入力します。コピープロセスは繰り返されないため、子オブジェクト自体のコピーは作成されません。浅いコピーの場合、オブジェクトの参照は他のオブジェクトにコピーされます。これは、オブジェクトのコピーに加えられた変更が元のオブジェクトに反映されることを意味します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加