Shallow Copy vs Deep Copy in Python: An Interview-Oriented Explanation
Source: Dev.to
Introduction
One of the most common Python interview questions sounds deceptively simple:
“What’s the difference between shallow copy and deep copy in Python?”
Interviewers use this question to test:
- Understanding of mutable vs. immutable objects
- Grasp of object references
- Ability to reason about side effects and bugs
- Knowledge of real‑world Python behavior (not just definitions)
This is especially important for backend, data, and machine‑learning roles.
Shallow Copy
A shallow copy creates a new container object, but it does not recursively copy the objects inside it. The outer object is copied, while the inner objects remain shared references.
import copy
original = [[1, 2], [3, 4]]
shallow = copy.copy(original)
shallow[0].append(99)
print(original) # [[1, 2, 99], [3, 4]]
print(shallow) # [[1, 2, 99], [3, 4]]
originalandshalloware different lists, but their inner lists point to the same memory.
Deep Copy
A deep copy creates a new container and recursively copies all nested objects, resulting in no shared references. The copied structure is fully independent.
import copy
original = [[1, 2], [3, 4]]
deep = copy.deepcopy(original)
deep[0].append(99)
print(original) # [[1, 2], [3, 4]]
print(deep) # [[1, 2, 99], [3, 4]]
- Changes in
deepdo not affectoriginal.
Analogy
- Shallow copy → copies the box, not the items inside.
- Deep copy → copies the box and everything inside it.
This analogy helps convey the concept quickly in interviews.
Common Ways to Copy in Python
| Operation | Type of Copy | Note |
|---|---|---|
list.copy() | Shallow | |
list[:] | Shallow | Slicing is always shallow |
dict.copy() | Shallow | |
copy.copy(obj) | Shallow | |
copy.deepcopy(obj) | Deep | More expensive (time & memory) |
b = a | No copy | Simple assignment shares the same object |
Important Pitfalls
-
Misconception: “Shallow copy copies everything once.”
- Reality: Nested mutable objects are shared.
-
Deep copy costs:
- Slower execution
- Higher memory usage
- May break assumptions about object identity
-
Immutable objects (e.g.,
int,str,tuple) do not cause shared‑state issues.
When to Avoid Deep Copy
- Large, deeply nested structures where performance matters
- Objects that hold external resources (files, DB connections)
- Situations where controlled mutation of shared data is acceptable
Custom Copy Behavior
Advanced interview candidates may mention that custom classes can control copying by implementing:
def __copy__(self):
# return a shallow copy of the instance
...
def __deepcopy__(self, memo):
# return a deep copy of the instance
...
This signals senior‑level understanding, as many frameworks rely on these hooks.
Structured Answer to the Interview Question
A shallow copy creates a new container but shares references to nested objects, while a deep copy recursively duplicates all objects. Shallow copies are faster and memory‑efficient but can cause side effects with mutable nested data. Deep copies avoid shared state but are more expensive. Python provides
copy.copy()for shallow copies andcopy.deepcopy()for deep copies.
Real‑World Bugs Related to Copying
- Shared references: Mutating a nested object in one copy unintentionally affects the other.
- Assuming independence: Treating a shallow copy as fully independent leads to subtle bugs.
Understanding why these bugs happen equips you to handle both interview scenarios and production code with confidence.