Skip to main content

Shallow & Deep Copy

>>> x = 3
>>> y = 3

x and y are assigned to the same object(3) the proof that this is really so can be provided with the help of the id-function:

>>> print(id(x), id(y))
10861256 10861256

so what happens if we assign a different value to one variable

>>> y = 2
>>> print(id(x) == id(y), x, y)
False 3 2

y now points to an integer object of its own

Shallow Copy

the copy-method can be used to create flat copies of lists

>>> list1 = ["3", "6", "9"]
>>> list2 = list1.copy()
>>> list2[1] = "x"
>>> print(list1)
['3', '6', '9']

>>> print(list2)
['3', 'x', '9']

but as soon as there are sublists in the list to be copied,


only pointers to these sublists are copied

>>> lst1 = ["a", "b",["cd", "dc"]]
>>> lst2 = lst1.copy()
>>> lst2[0] = "c"
>>> lst2[2][0] = "f"
>>> print(lst1)
['a', 'b', ['f', 'dc']]

Deep Copy

one solution for the problem just described is the module copy which provides the deepcopy function

>>> from copy import deepcopy
>>> lst1 = ["a", "b",["cd", "dc"]]
>>> lst2 = deepcopy(lst1)


>>> lst2[2][1] = "d"
>>> lst2[0] = "c"
>>> print(lst2)
['c', 'b', ['cd', 'd']]

>>> print(lst1)
['a', 'b', ['cd', 'dc']]

Deep Copy Dictionaries

deepcopy from the module copy works for any python object from copy import deepcopy

>>> d = {"a": 3, "b": 4}
>>> copy_of_d = deepcopy(d)
>>> d["c"] = 1
>>> d
{'a': 3, 'b': 4, 'c': 1}
>>> copy_of_d
{'a': 3, 'b': 4}

also the method copy creates only a flat copy

>>> p = {"John": {"weight": 87.8, "Height": 187.5}}
>>> p = {"John": {"weight": 87.8, "Height": 187.5},"Jane":
{"weight": 60.6, "height": 168.4}}
>>> p2 = p.copy()
>>> p["Jane"]["weight"] -= 0.4
>>> p2
{'John': {'weight': 87.8, 'Height': 187.5},
'Jane': {'weight': 60.2, 'height': 168.4}}

>>> p2 = deepcopy(p)
>>> p["Jane"]["weight"] -= 0.2
>>> p2["Jane"]["weight"]
60.0

>>> p["Jane"]["weight"]
59.8

Copy Lists

in this example we create a flat copy of a list

>>> colors1 = ["red", "blue"]
>>> colors2 = colors1
>>> print(colors1)
['red', 'blue']

>>> print(colors2)
['red', 'blue']

>>> print(id(colors1), id(colors2))
140535031048896 140535031048896

>>> colors1 = ["blue", "yellow"]
>>> print(colors1)
['blue', 'yellow']

>>> print(colors2)
['red', 'blue']

>>> colors1 = ["red", "blue"]
>>> colors2 = colors1
>>> colors2[1] = "green"
>>> print(colors1)
['red', 'green']

>>> print(colors2)
['red', 'green']

as we have already seen, in the assignment colors1 = colors2 only one reference to the same list is created so changes within the list object apply to colors1 and colors2 since they point to the same object