1. ホーム
  2. python

[解決済み] dict.copy()を理解する - 浅いか深いか?

2022-03-19 22:26:58

質問

のドキュメントを読んでいると dict.copy() には、辞書の浅いコピーを作成すると書かれています。私が追いかけている本(Beazley's Python Reference)にも同じことが書いてあります。

m.copy()メソッドでは に含まれる項目のコピー マッピングオブジェクトを作成し、それを 新しいマッピングオブジェクトを作成します。

これを考えてみましょう。

>>> original = dict(a=1, b=2)
>>> new = original.copy()
>>> new.update({'c': 3})
>>> original
{'a': 1, 'b': 2}
>>> new
{'a': 1, 'c': 3, 'b': 2}

の値が更新されると仮定したわけです。 original (そして'c': 3を追加)も浅いコピーをしているので。リストに対して行う場合のように。

>>> original = [1, 2, 3]
>>> new = original
>>> new.append(4)
>>> new, original
([1, 2, 3, 4], [1, 2, 3, 4])

これは期待通りに動作しています。

どちらもシャローコピーなので、なぜか dict.copy() が期待通りに動かないのですが?あるいは、私の浅いコピーと深いコピーについての理解に誤りがあるのでしょうか?

どのように解決するのですか?

浅いコピーというのは コンテンツ は値でコピーされるのではなく、単に新しい参照を作成するだけです。

>>> a = {1: [1,2,3]}
>>> b = a.copy()
>>> a, b
({1: [1, 2, 3]}, {1: [1, 2, 3]})
>>> a[1].append(4)
>>> a, b
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})

これに対して、ディープコピーでは、すべての内容を値でコピーします。

>>> import copy
>>> c = copy.deepcopy(a)
>>> a, c
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})
>>> a[1].append(5)
>>> a, c
({1: [1, 2, 3, 4, 5]}, {1: [1, 2, 3, 4]})

だから

  1. b = a : リファレンス割り当て、Make ab は同じオブジェクトを指しています。

    <イグ

  2. b = a.copy() : 浅いコピー。 ab は2つの独立したオブジェクトになりますが、それらのコンテンツはまだ同じ参照を共有しています。

  3. b = copy.deepcopy(a) : ディープコピー ab の構造と内容は完全に分離される。

    <イグ