In Python, object copying can be shallow (shallow copy) and deep (deep copy). A shallow copy creates a new container, but nested objects are not copied; instead, references to the same objects are used. A deep copy recursively creates new copies of all nested objects, ensuring independence of the copy.
The copy module provides the methods copy() (shallow copy) and deepcopy() (deep copy):
import copy original = [[1, 2], [3, 4]] shallow = copy.copy(original) deep = copy.deepcopy(original) shallow[0][0] = 99 print(original) # [[99, 2], [3, 4]] ← the original object has changed! deep[1][1] = 42 print(original) # [[99, 2], [3, 4]] - hasn't changed
What is the difference between the operator
list2 = list1and using copy.copy(list1)?
Answer: The operator list2 = list1 creates a new reference to the same object. copy.copy(list1) makes a shallow copy, creating a new list object but with the same inner objects. For nested structures, shallow copying is not enough — a deep copy is needed.
Story
When developing a REST API, data from the template was copied using normal assignment (
data = template). The next request accidentally modified the "template" for all subsequent users since the same reference was used.
Story
In the reporting module, data was copied using
copy.copy(), even though the structure was nested (lists in dictionaries). Modifications in the copy unexpectedly reflected in the original data, causing errors in the statistics.
Story
In one banking project, an incorrect copy of a complex nested object through
copy.copy()(instead ofdeepcopy()) led to the loss of transaction history — new operations overwrote the old ones since the nested elements were shared.