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”が追加されていて、深いコピーでは追加されない。