6.5 Copying Objects
The difference between assignment, a shallow copy, and a deep copy in Python, when each is appropriate, and how the copy module's copy() and deepcopy() behave differently on nested mutable objects.
When shared references aren’t what you want (see 6.2 Objects and Variable References), Python offers three distinct ways to copy a mutable object, each with a different depth.
Shallow copy duplicates the outer container but shares nested objects; deep copy duplicates everything, recursively.
Assignment Copy
b = a is not a copy at all — both names reference the identical object. Included here only to contrast with the two real copy types below.
Shallow Copy
What Is It?
Creates a new outer object, but the elements inside it are still shared references to the same nested objects as the original.
Why Is It Used?
Fast, and sufficient when the container holds only immutable elements, or nested mutation isn’t a concern.
Deep Copy
What Is It?
Recursively copies the object and everything it contains, so the result is completely independent of the original at every level.
Why Is It Used?
Needed whenever the original contains nested mutable objects (like a list of lists) and full independence is required.
The copy Module
The standard library’s copy module provides both copy() and deepcopy() — here’s all three approaches compared directly:
>>> import copy
>>> original = [1, 2, [3, 4]]
>>> assign_copy = original
>>> shallow = copy.copy(original)
>>> deep = copy.deepcopy(original)
>>> original[2].append(99) # mutate the nested list
>>> original
[1, 2, [3, 4, 99]]
>>> assign_copy # same object -- sees the change
[1, 2, [3, 4, 99]]
>>> shallow # outer copied, but nested list is SHARED -- sees it
[1, 2, [3, 4, 99]]
>>> deep # fully independent -- does NOT see the change
[1, 2, [3, 4]]
Quick Interview Answer
“
b = aisn’t a copy at all — both names share one object.copy.copy()creates a shallow copy: a new outer container, but its nested elements are still shared with the original, so mutating a nested list through either one is visible through both.copy.deepcopy()recursively copies everything, producing a result that’s fully independent at every level. Use shallow copy when the container only holds immutable elements; use deep copy whenever it holds nested mutable objects and true independence is required.”
Common Mistakes
- Assuming
copy.copy()produces a fully independent object — it only copies the outer container; nested mutable objects are still shared. - Reaching for
copy.deepcopy()by default even when not needed — it’s slower and unnecessary for flat structures or containers of immutable values. - Using
list(original)ororiginal[:]expecting a deep copy — both are shallow copies, identical in depth tocopy.copy().
Add More Questions to This Guide
Know a question that should be here? Share it and help the community!
Open Google Form