When working with mutable objects (like lists, dictionaries, sets, etc.), copying them can behave differently depending on how deep the copy goes.
Python provides two main ways to copy objects:
β
Shallow Copy
β
Deep Copy
Letβs understand both with clear examples and visuals π
πΉ 1. What is a Copy in Python?
When you assign one variable to another:
a = [1, 2, 3]
b = aβ‘οΈ Both a and b point to the same memory location.
If you modify b, a will change too β because no actual copy is made.
Example:
a = [1, 2, 3]
b = a
b.append(4)
print(a)Output:
[1, 2, 3, 4]β
Both a and b refer to the same list.
To actually copy objects, you can use:
- Shallow Copy β
copy.copy(obj) - Deep Copy β
copy.deepcopy(obj)
πΉ 2. Import the copy Module
Before using either, you need:
import copyπΉ 3. Shallow Copy
A shallow copy creates a new object, but does not create copies of nested objects inside it.
Instead, it just copies references to the inner objects.
β Syntax:
copy.copy(object)π§© Example: Shallow Copy of Nested List
import copy
original = [[1, 2, 3], [4, 5, 6]]
shallow = copy.copy(original)
shallow[0][0] = 99
print("Original:", original)
print("Shallow:", shallow)Output:
Original: [[99, 2, 3], [4, 5, 6]]
Shallow: [[99, 2, 3], [4, 5, 6]]β
Changing the inner list in shallow also changed original β
because nested objects were not copied, only referenced.
π§ Visualization:
original β [[1, 2, 3], [4, 5, 6]]
β β
βββ shared ββ (same nested lists)
shallow β [[1, 2, 3], [4, 5, 6]]Both original and shallow share the same inner lists.
π§© However, modifying the top-level list works independently:
shallow.append([7, 8])
print("Original:", original)
print("Shallow:", shallow)Output:
Original: [[99, 2, 3], [4, 5, 6]]
Shallow: [[99, 2, 3], [4, 5, 6], [7, 8]]β
The outer list is different (copied),
but inner lists still share memory.
πΉ 4. Deep Copy
A deep copy creates a completely independent copy of the original object β
including all nested objects.
That means any modification in one object will not affect the other.
β Syntax:
copy.deepcopy(object)π§© Example: Deep Copy of Nested List
import copy
original = [[1, 2, 3], [4, 5, 6]]
deep = copy.deepcopy(original)
deep[0][0] = 99
print("Original:", original)
print("Deep Copy:", deep)Output:
Original: [[1, 2, 3], [4, 5, 6]]
Deep Copy: [[99, 2, 3], [4, 5, 6]]β
Changes made to deep do not affect original.
All nested elements are fully cloned.
π§ Visualization:
original β [[1, 2, 3], [4, 5, 6]]
β β
deep β [[1, 2, 3], [4, 5, 6]]β Completely new objects at all levels β no shared references.
πΉ 5. Shallow vs Deep Copy β Side-by-Side Example
import copy
original = [[1, 2], [3, 4]]
shallow = copy.copy(original)
deep = copy.deepcopy(original)
# Modify inner list
original[0][0] = 99
print("Original:", original)
print("Shallow:", shallow)
print("Deep:", deep)Output:
Original: [[99, 2], [3, 4]]
Shallow: [[99, 2], [3, 4]]
Deep: [[1, 2], [3, 4]]β Only the deep copy remains unaffected.
πΉ 6. Shallow Copy Using Built-in Methods
You can create shallow copies using:
list.copy()
list[:]
copy.copy()Example:
a = [1, 2, 3]
b = a.copy() # shallow copy
c = a[:] # shallow copy
print(a == b == c) # True
print(a is b) # False (different objects)β
Works fine for 1D lists (no nesting).
But not safe for nested structures β still shares references.
πΉ 7. Performance Note
| Operation | Speed | Memory Usage |
|---|---|---|
| Shallow Copy | π’ Fast | Low |
| Deep Copy | π΄ Slower | High (copies all nested data) |
β
Use shallow copy when you only need a duplicate of the outer object.
β
Use deep copy when you need a fully independent copy of nested structures.
π§Ύ Summary Table
| Feature | Shallow Copy | Deep Copy |
|---|---|---|
| Function | copy.copy() | copy.deepcopy() |
| Copies Outer Object? | β Yes | β Yes |
| Copies Inner Objects? | β No (references only) | β Yes (new copies) |
| Independent? | Partially | Completely |
| Speed | Faster | Slower |
| Memory Usage | Less | More |
| Example Effect | Change in nested list affects both | Changes isolated |
| Use When | Nested data wonβt be modified | Independent copy needed |
πΉ 8. Real-Life Example β Studentsβ Marks
import copy
students = [["Alice", [85, 90]], ["Bob", [75, 80]]]
shallow = copy.copy(students)
deep = copy.deepcopy(students)
# Modify one studentβs marks
students[0][1][0] = 100
print("Original:", students)
print("Shallow:", shallow)
print("Deep:", deep)Output:
Original: [['Alice', [100, 90]], ['Bob', [75, 80]]]
Shallow: [['Alice', [100, 90]], ['Bob', [75, 80]]]
Deep: [['Alice', [85, 90]], ['Bob', [75, 80]]]β
shallow reflects the inner list change;
β
deep remains untouched.
β In short:
- Shallow Copy (
copy.copy())
β Copies the object, but shares nested references.- Deep Copy (
copy.deepcopy())
β Creates a fully independent clone of the object, including nested ones.
π§© Final Example (Quick Recap)
import copy
data = [[1, 2, 3], [4, 5, 6]]
shallow = copy.copy(data)
deep = copy.deepcopy(data)
data[0][0] = 999
print("Original:", data)
print("Shallow:", shallow)
print("Deep:", deep)Output:
Original: [[999, 2, 3], [4, 5, 6]]
Shallow: [[999, 2, 3], [4, 5, 6]]
Deep: [[1, 2, 3], [4, 5, 6]]β
Shallow copy shares nested references.
β
Deep copy makes a complete, independent clone.
