Python 浅いコピーと深いコピー

  • 23
    いいね
  • 2
    コメント

最近リストの浅いコピーと深いコピーについて調べることがあったのでメモ。
(参考:8.10. copy — 浅いコピーおよび深いコピー操作

通常、リストをコピーして片方のリストの値を変更すると、もう一つのリストも値が変わってしまう (浅いコピー)

2017/9/17 追記
コメントで指摘をいただきました.dlpyvimさんありがとうございます.

上記の説明の例は浅いコピーとは言わないと思います。
浅いコピーとはcopy.copy()の事です。
copy.deepcopy()との違いは、オブジェクトの中にオブジェクトがあった場合、参照を挿入するか、再帰的にコピーするかの違いです。

>>> l = [1, 2, 3]
>>> l2 = l
>>> l
[1, 2, 3]
>>> l2
[1, 2, 3]
>>> l[2] = 4
>>> l
[1, 2, 4]
>>> l2
[1, 2, 4]

これを回避するには、deepcopy()関数を使用すればよいみたい(深いコピー)。

>>> l = [1, 2, 3]
>>> import copy
>>> l2 = copy.deepcopy(l)
>>> l
[1, 2, 3]
>>> l2
[1, 2, 3]
>>> l[2] = 4
>>> l
[1, 2, 4]
>>> l2
[1, 2, 3]

空リストを作る時もこれに注意しないと、勝手に値が入ってしまったりして困る。

>>> empty = [[]] * 5
>>> empty
[[], [], [], [], []]
>>> empty[0].append(1)
>>> empty
[[1], [1], [1], [1], [1]]

このような2次元の空リストを作りたいときは、リスト内包表記を使うといいみたい。

>>> empty = [[] for x in range(5)]
>>> empty
[[], [], [], [], []]
>>> empty[0].append(1)
>>> empty
[[1], [], [], [], []]