ペンドリブン

1985年生まれ 仕事・家庭・etc. 雑記

*

pythonのcopyとdeepcopyの使い分け

      2016/01/15

pythonのcopyには

浅い(shallow)コピーと深い(deep)コピー

がある。

  
import copy
list = [{"a": "1"}, {"b": "2"}, {"c": "3"}]
list_copy = copy.copy(list)
list[0]["b"] = 2
print list
[{'a': '1', 'b': 2}, {'b': '2'}, {'c': '3'}]
print list_copy
[{'a': '1', 'b': 2}, {'b': '2'}, {'c': '3'}]

copy.copy()で上記のような値に「リスト」や「辞書」などの複合オブジェクトを持つものをコピーすると、listの1つ目の辞書に{“b”: “2”}を追加するとlist_copyのにも{“b”: “2”}が追加されている。

これを深いコピーでやるとlist_copyにはcopyに追加したものが反映されない。

import copy
list = [{"a": "1"}, {"b": "2"}, {"c": "3"}]
list_copy = copy.deepcopy(list)
list[0]["b"] = 2
print list
[{'a': '1', 'b': 2}, {'b': '2'}, {'c': '3'}]
print list_copy
[{'a': '1'}, {'b': '2'}, {'c': '3'}]

ドキュメントには下記のようにある。

浅いコピー (shallow copy) は新たな複合オブジェクトを作成し、 その後 (可能な限り) 元のオブジェクト中に見つかったオブジェクトに対する 参照 を挿入します。

深いコピー (deep copy) は新たな複合オブジェクトを作成し、 その後元のオブジェクト中に見つかったオブジェクトの コピー を挿入します。

http://www.python.jp/doc/release/library/copy.html?highlight=deepcopy

おそらく浅いコピーで作成したlist_copyには、listを参照するようなリンクが挿入され、深いコピーではlistの持っているオブジェクトその物がコピーされてlist_copyに挿入される感じなのだと思う。

なお、下記はlist_copyの内容が変わるので浅いコピーになる。

import copy
list = [{"a": "1"}, {"b": "2"}, {"c": "3"}]
list_copy = list[:]
list[0]["b"] = 2
print list
[{'a': '1', 'b': 2}, {'b': '2'}, {'c': '3'}]
print list_copy
[{'a': '1', 'b': 2}, {'b': '2'}, {'c': '3'}]

追記

上記のlist[0][“b”] = 2をlist_copy[0][“b”] = 2にしても、浅いコピーではlistに”b”: “2”が追加されていて、深いコピーでは追加されない。

 - プログラム