pythonのリスト複製,コピーについての注意点をまとめました.
(間違いありましたらご指摘お願いします)
目次
1. 「代入」≠「コピー」
2. 多重リストの場合も注意
1. 「代入」≠「コピー」
list1の内容をlist2に複製しようと思って,通常の変数の代入で
list2=list1
とすると,list1,list2の一方に対する操作が他方にも反映されてしまいます.
これは、変数にはリストのコピーではなく、リストへの参照が代入され、リストを共有するためです.
リストを安全に複製するためには
list2=list1.copy()
とすると,list2にはlist1のコピーが代入されるので,それぞれ独立した別のオブジェクトとして扱うことができます.
以下では,実際に通常の代入とコピーしてから代入した場合の違いについて,元のlistに変更を加えた場合に変更がどのように反映される(されない)のかを示します.
array=[1,2,3,4,5]
copied_array1=array #通常の代入
copied_array2=array.copy() #copy()を使ってコピーしたリストを代入
array[0]=100 #array
print(f"array : {array}")
print(f"copied_array1 : {copied_array1}")
print(f"copied_array2 : {copied_array2}")
print(f"arrayのid : {id(array)}")
print(f"copied_array1のid : {id(copied_array1)}")
print(f"copied_array2のid : {id(copied_array2)}")
array : [100, 2, 3, 4, 5]
copied_array1 : [100, 2, 3, 4, 5]
copied_array2 : [1, 2, 3, 4, 5]
arrayのid : 4414692224
copied_array1のid : 4414692224
copied_array2のid : 4414696320
copied_array1はarrayを代入したもの,copied_array2はarrayのコピーを代入したものです.
arrayの先頭要素の値を変更すると,copied_array1(通常代入の方)には値の変更が反映されてしまっていますが,copied_array2(コピーの方)には反映されていません.
また,array,copied_array1,copied_array2のid(オブジェクトに固有の識別子)を比較すると,arrayとcopied_array1はidが同じで,copied_array2のidは異なります.
(idが同じオブジェクトに対する操作は,同idのオブジェクト全てに反映されてしまう)
2. 多重リストの場合も注意
また,以下のケースでも注意が必要です
array=[1,2,3]
Array_List1=[]
Array_List2=[]
Array_List1.append(array)
Array_List2.append(array.copy())
array[0]=100
print(array)
print(Array_List1[0])
print(Array_List2[0])
>[100, 2, 3]
>[100, 2, 3] #arrayに対する変更が反映されている
>[1,2,3] #arrayに対する変更が反映されていない
このケースでは,arrayの参照を直接Array_List1に追加(append)しているために,arrayの変更がArray_List内に追加した要素にも反映されてしまっています.一方,コピーを追加したArray_List2の方では,arrayの変更が反映されません.
結論
代入とコピーの違いについてまとめました.
コピーの方が,オブジェクト間の独立性が保証されるので安全.
参考