変数は値の実体ではないことがある
_リスト_や_ディクショナリ_といった特定の型を扱う際、変数は値の実体とは異なり、実体を参照している。
以下のプログラムの実行結果から変数の性質が確認できる。
l1 = []
l1.append(0)
l2 = l1
l2.append(1)
print('l1 = ' ,l1)
print('l2 = ' ,l2)
実行結果
l1 = [0, 1]
l2 = [0, 1]
リストl2
へリストl1
を代入後、l2
のみに値を追加したが、l1
にも同様の値が追加されている。これは、l1
もl2
も保持しているのは参照情報であり、参照の先にある実体は同一のものを共有しているからである。
実体そのものをコピーする
代入を行うだけでは値そのものはコピーされない問題を解決するために、copy()
メソッドを用いる。
l1 = []
l1.append(0)
l3 = l1.copy()
l3.append(1)
print('l1 = ' ,l1)
print('l3 = ' ,l3)
実行結果
l1 = [0]
l3 = [0, 1]
しかし、copy()
メソッドを用いても、リストの要素が参照である場合はその参照先まではコピーされない。
l4 = [[]]
l4[0].append(0)
l5 = l4.copy()
l5[0].append(1)
print('l4 = ' ,l4)
print('l5 = ' ,l5)
実行結果
l4 = [[0, 1]]
l5 = [[0, 1]]
リストに含まれる要素の参照先まで全てコピーしたい場合にはcopy
パッケージに含まれるdeepcopy()
メソッドを用いれば良い。
import copy
l4 = [[]]
l4[0].append(0)
l6 = copy.deepcopy(l4)
l6[0].append(1)
print('l4 = ' ,l4)
print('l6 = ' ,l6)
実行結果
l4 = [[0]]
l6 = [[0, 1]]