「浅い」コピー辞書を更新しても「元の」辞書が更新されないのはなぜですか? [重複] 質問する

「浅い」コピー辞書を更新しても「元の」辞書が更新されないのはなぜですか? [重複] 質問する

のドキュメントを読んでいると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}

したがって、浅いコピーを実行しているため、これにより値が更新され ('c': 3 が追加される) と想定しましたoriginal。リストに対してこれを行う場合のように:

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

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

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

ベストアンサー1

「浅いコピー」とは、辞書の内容が値によってコピーされるのではなく、新しい参照が作成されることを意味します。

>>> 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: 参照代入。Makeaと がb同じオブジェクトを指すようにします。

    「a = b」の図: 「a」と「b」は両方とも「{1: L}」を指し、「L」は「[1, 2, 3]」を指します。

  2. b = a.copy(): 浅いコピーであり、a2bつの独立したオブジェクトになりますが、その内容は同じ参照を共有します。

    'b = a.copy()' の図: 'a' は '{1: L}' を指し、'b' は '{1: M}' を指し、'L' と 'M' は両方とも '[1, 2, 3]' を指します。

  3. b = copy.deepcopy(a): ディープコピー、aおよびbの構造とコンテンツは完全に分離されます。

    'b = copy.deepcopy(a)' の図: 'a' は '{1: L}' を指し、'L' は '[1, 2, 3]' を指します。'b' は '{1: M}' を指し、'M' は '[1, 2, 3]' の別のインスタンスを指します。

おすすめ記事