The problem
When you copy a list containing other lists, a simple assignment doesn't create a true copy—both variables point to the same object. This can cause unexpected changes.
Shallow copy
A shallow copy creates a new object, but nested objects are still shared:
import copy
original = [[1, 2, 3], [4, 5, 6]]
shallow = copy.copy(original)
# Modify nested list:
shallow[0][0] = 99
print(original) # [[99, 2, 3], [4, 5, 6]] — changed!
print(shallow) # [[99, 2, 3], [4, 5, 6]]
Deep copy
A deep copy creates completely independent copies of all nested objects:
import copy
original = [[1, 2, 3], [4, 5, 6]]
deep = copy.deepcopy(original)
# Modify nested list:
deep[0][0] = 99
print(original) # [[1, 2, 3], [4, 5, 6]] — unchanged!
print(deep) # [[99, 2, 3], [4, 5, 6]]
When to use each
- Shallow copy: When nested objects are immutable (like strings, numbers) or you want to share nested data
- Deep copy: When you need completely independent copies of nested mutable objects
For simple lists
# For flat lists, these work the same:
list1 = [1, 2, 3]
list2 = list1.copy() # or list(list1) or list1[:]
list2[0] = 99
print(list1) # [1, 2, 3] — unchanged