Pythonでcopyとdeepcopy

Pythonの辞書にはにはdict.copy()というメソッドが用意されているが,これは注意しないとはまります. 以下を見てください.

In [1]: d = {"a":1, "b":range(10)}

In [2]: d
Out[2]: {'a': 1, 'b': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}

In [3]: d2 = d.copy()

In [4]: d2
Out[4]: {'a': 1, 'b': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}

In [5]: d2["b"].append(10)

In [6]: d
Out[6]: {'a': 1, 'b': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}

In [7]: d2
Out[7]: {'a': 1, 'b': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}

このように,値にリスト(おそらく辞書や集合も)を持つような辞書をコピーすると, 値であるリストはコピーされません(番地への参照を持つだけ). そのため,dをコピーしたd2のキーbの値を変更すると,dの内容も変わってしまいます. これを解決するために,Pythonにはcopyというモジュールがあります. copy.deepcopy()を使うことによって,この問題を解決できます. 以下使用例です.

In [8]: from copy import deepcopy

In [9]: d = {"a":1, "b":range(10)}

In [10]: d
Out[10]: {'a': 1, 'b': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}

In [11]: d2 = deepcopy(d)

In [12]: d2
Out[12]: {'a': 1, 'b': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}

In [13]: d2["b"].append(10)

In [14]: d
Out[14]: {'a': 1, 'b': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}

In [15]: d2
Out[15]: {'a': 1, 'b': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}

僕はよくこういうのにはまるので,皆さんもお気をつけて( ´ゝ`)

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中