Introduction π
When copying objects in Python, it's important to understand the difference betweenshallow copy and deep copy. Both create new objects β but they behave very differently with nested (mutable) data.
Note
π‘ Deep Copy β Copies the outer object + all nested objects
1. Importing the copy Module π§±
import_copy.py
import copy2. What is a Shallow Copy? πͺ
A shallow copy creates a new object, but **nested mutable objects are shared (not copied)**.
Using copy.copy()
shallow_basic.py
import copy
a = [1, 2, [3, 4]]
b = copy.copy(a)
b[0] = 100 # modifies only b
b[2][0] = 999 # modifies the shared nested list
print("a =", a)
print("b =", b)β Outer list is copied
β Inner list is shared β shallow copy problem
3. What is a Deep Copy? π§ͺ
A deep copy creates a fully independent clone: all nested lists, dictionaries, sets, and objects are copied recursively.
Using copy.deepcopy()
deep_basic.py
import copy
a = [1, 2, [3, 4]]
b = copy.deepcopy(a)
b[2][0] = 999 # modifies only b's nested list
print("a =", a)
print("b =", b)β Completely independent copy
4. Visual Difference π
| Operation | Shallow Copy | Deep Copy |
|---|---|---|
| Create new outer object? | Yes | Yes |
| Copy nested objects? | No | Yes |
| Nested changes affect original? | Yes | No |
| Performance | Faster | Slower (copies everything) |
5. Shallow Copy Examples π
Shallow Copy of a List
shallow_list.py
a = [[1,2], [3,4]]
b = a.copy() # listβs own shallow copy
b[0][1] = 999
print(a) # nested list changed in a
print(b)Shallow Copy of a Dictionary
shallow_dict.py
d1 = {"a": 1, "b": [10, 20]}
d2 = d1.copy()
d2["b"][0] = 999
print(d1) # original changed!
print(d2)6. Deep Copy Examples π§
Deep Copy of List
deep_list.py
import copy
a = [[1,2], [3,4]]
b = copy.deepcopy(a)
b[0][1] = 999
print(a) # unchanged
print(b)Deep Copy of Dictionary
deep_dict.py
import copy
d1 = {"a": 1, "b": [10, 20]}
d2 = copy.deepcopy(d1)
d2["b"][0] = 999
print(d1) # unchanged
print(d2)7. When to Use Which? π§©
- β Use **shallow copy** for simple, non-nested data
- β Use **deep copy** for complex nested structures
- β Avoid deep copy when performance is critical
Note
8. Special Case β Immutable Types π§
Immutable objects (int, float, str, tuple) are always safe: copying them behaves the same as assignment.
immutable_copy.py
x = 10
y = copy.copy(x)
z = copy.deepcopy(x)
print(x == y == z) # True9. Real-World Example β Avoid Shared References β οΈ
reference_issue.py
a = [[0] * 3] * 3 # BAD: all rows share same list
a[0][0] = 999
print(a) # all rows modified!β Use deep copy or list comprehension to avoid this issue
10. Real-World Example β Safe Copying of Configurations βοΈ
config_copy.py
import copy
default_config = {
"theme": "dark",
"options": {"font": "Arial", "size": 12}
}
user_config = copy.deepcopy(default_config)
user_config["options"]["size"] = 18
print(default_config) # unchanged
print(user_config)Cheat Sheet π
| Copy Type | Function | Copies Nested Objects? |
|---|---|---|
| Shallow Copy | copy.copy() | No |
| Deep Copy | copy.deepcopy() | Yes |
| List Shallow Copy | list.copy() | No |
| Dict Shallow Copy | dict.copy() | No |
Conclusion π
You now fully understand Shallow Copy vs Deep Copy in Python! Want the next topic? Try Mutable vs Immutable Objects, Garbage Collection, or Memory Management. Just tell me! π