In the realm of Python, assigning one variable to another may not always be as straightforward as it seems. When dealing with mutable objects like lists and dictionaries, a mere assignment creates a reference, not a true copy. The impact? Modifications to one affect the other. Enter the copy module, offering salvation in the form of shallow and deep copies.
Assignment Operation: The Reference Link
list_a = [1, 2, 3, 4, 5]
list_b = list_a
list_a[0] = -10
print(list_a) # [-10, 2, 3, 4, 5]
print(list_b) # [-10, 2, 3, 4, 5]
A change in one echoes in the other, a symphony of shared references.
Shallow Copy: Tread Lightly on Nested Grounds
import copy
list_a = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
list_b = copy.copy(list_a)
list_b[0][0] = -10
print(list_a) # [[-10, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
print(list_b) # [[-10, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
Shallow copies exhibit caution: they grant independence at the first level but remain entangled deeper.
Deep Copy: Breaking Chains
import copy
list_a = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
list_b = copy.deepcopy(list_a)
list_b[0][0] = -10
print(list_a) # [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
print(list_b) # [[-10, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
Deep copies liberate, ensuring modifications in one realm don't cast shadows on another.
Navigating Custom Objects
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# Reference link
p1 = Person('Alex', 27)
p2 = p1
p2.age = 28
print(p1.age) # 28
print(p2.age) # 28
# Shallow copy
import copy
p1 = Person('Alex', 27)
p2 = copy.copy(p1)
p2.age = 28
print(p1.age) # 27
print(p2.age) # 28
Understanding copying is vital, especially when nested structures or custom objects come into play. Shallow copies tiptoe, while deep copies break free. Choose wisely and code confidently in the dynamic realm of Python!