Understanding dict.copy() - shallow or deep?
By "shallow copying" it means the content of the dictionary is not copied by value, but just creating a new reference.
>>> 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]})
In contrast, a deep copy will copy all contents by value.
>>> 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]})
So:
b = a
: Reference assignment, Makea
andb
points to the same object.b = a.copy()
: Shallow copying,a
andb
will become two isolated objects, but their contents still share the same referenceb = copy.deepcopy(a)
: Deep copying,a
andb
's structure and content become completely isolated.
Take this example:
original = dict(a=1, b=2, c=dict(d=4, e=5))new = original.copy()
Now let's change a value in the 'shallow' (first) level:
new['a'] = 10# new = {'a': 10, 'b': 2, 'c': {'d': 4, 'e': 5}}# original = {'a': 1, 'b': 2, 'c': {'d': 4, 'e': 5}}# no change in original, since ['a'] is an immutable integer
Now let's change a value one level deeper:
new['c']['d'] = 40# new = {'a': 10, 'b': 2, 'c': {'d': 40, 'e': 5}}# original = {'a': 1, 'b': 2, 'c': {'d': 40, 'e': 5}}# new['c'] points to the same original['d'] mutable dictionary, so it will be changed
It's not a matter of deep copy or shallow copy, none of what you're doing is deep copy.
Here:
>>> new = original
you're creating a new reference to the the list/dict referenced by original.
while here:
>>> new = original.copy()>>> # or>>> new = list(original) # dict(original)
you're creating a new list/dict which is filled with a copy of the references of objects contained in the original container.