変数の代入
リストなどのミュータブルオブジェクトのコピーには注意を要する。
単に変数を代入した場合、元のオブジェクトへの変更は同じ参照の全ての変数に影響する。
1 2 3 4 5 6 7 8 9 10 |
lst_org = [1, 2, 3] print("original list : {}".format(lst_org)) lst_assign = lst_org lst_assign[0] = 0 print("assigned and modified: {}".format(lst_assign)) print("original list : {}".format(lst_org)) # original list : [1, 2, 3] # assigned and modified: [0, 2, 3] # original list : [0, 2, 3] |
copy()
関数・copy()
メソッド
copy
モジュールのcopy()関
数を使うと、リストの各要素のインスタンスが新たに生成され、その内容がコピーされる。このため、コピー元への変更の影響はない。
1 2 3 4 5 6 7 8 9 10 11 12 |
import copy lst_org = [1, 2, 3] print("original list : {}".format(lst_org)) lst_copy = copy.copy(lst_org) lst_copy[0] = 0 print("copied and modified: {}".format(lst_copy)) print("original list : {}".format(lst_org)) # original list : [1, 2, 3] # copied and modified: [0, 2, 3] # original list : [1, 2, 3] |
deepcopy()関数による完全な複製
2次元配列など、ミュータブルオブジェクトの要素がミュータブルな場合は、copy()
だけでは各要素への参照が変わらないため、下位の要素の変更が波及する。このような上位要素のみに対するコピーをシャローコピーと呼ぶ。
1 2 3 4 5 6 7 8 9 10 |
lst_org = [[1, 2, 3], [4, 5, 6]] print("original list : {}".format(lst_org)) lst_copy = copy.copy(lst_org) lst_copy[0][0] = 0 print("copied and modified: {}".format(lst_copy)) print("original list : {}".format(lst_org)) # original list : [[1, 2, 3], [4, 5, 6]] # copied and modified: [[0, 2, 3], [4, 5, 6]] # original list : [[0, 2, 3], [4, 5, 6]] |
ミュータブルオブジェクトを要素に持つミュータブルオブジェクトの完全な複製を得るには、copy.deepcopy()
関数を使う。
1 2 3 4 5 6 7 8 9 10 |
lst_org = [[1, 2, 3], [4, 5, 6]] print("original list : {}".format(lst_org)) lst_deepcopy = copy.deepcopy(lst_org) lst_deepcopy[0][0] = 0 print("deepcopied and modified: {}".format(lst_deepcopy)) print("original list : {}".format(lst_org)) # original list : [[1, 2, 3], [4, 5, 6]] # deepcopied and modified: [[0, 2, 3], [4, 5, 6]] # original list : [[1, 2, 3], [4, 5, 6]] |
リストのコピーの別方法
copy()
関数はcopy
モジュールをインポートする必要があるが、以下の方法はcopy
モジュールがなくても同じ結果が得られる。
copy()
メソッド
リストのcopy()
メソッドは、copy.copy()
関数と同じく各要素の複製を生成する。
1 2 3 4 5 6 7 8 9 10 |
lst_org = [1, 2, 3] print("original list : {}".format(lst_org)) lst_copy = lst_org.copy() lst_copy[0] = 0 print("copied and modified: {}".format(lst_copy)) print("original list : {}".format(lst_org)) # original list : [1, 2, 3] # copied and modified: [0, 2, 3] # original list : [1, 2, 3] |
[:]
リストのスライスは元のリストの要素を生成し、新たなリストを返す。スライスを全要素[:]
とすることで、元のリストの複製が得られる。
1 2 3 4 5 6 7 8 9 10 |
lst_org = [1, 2, 3] print("original list : {}".format(lst_org)) lst_copy = lst_org[:] lst_copy[0] = 0 print("[:] and modified: {}".format(lst_copy)) print("original list : {}".format(lst_org)) # original list : [1, 2, 3] # [:] and modified: [0, 2, 3] # original list : [1, 2, 3] |
ただし、copy()
メソッドもスライスによる方法もシャローコピーなので、多次元配列などのディープコピーはできない。
1 2 3 4 5 6 7 8 9 10 |
lst_org = [[1, 2, 3], [4, 5, 6]] print("original list : {}".format(lst_org)) lst_copy = lst_org[:] lst_copy[0][0] = 0 print("[:] and modified: {}".format(lst_copy)) print("original list : {}".format(lst_org)) # original list : [[1, 2, 3], [4, 5, 6]] # [:] and modified: [[0, 2, 3], [4, 5, 6]] # original list : [[0, 2, 3], [4, 5, 6]] |