i am not getting the difference between shallow copy and deep copy. copy.copy and copy.deepcopy() gives the exact same output. Their memory location seems to be different than the other but the reference address has confused me a lot.
What are some differences between a Shallow Copy and Deep Copy?
194 views Asked by KAVYA SHARMA AtThere are 3 answers
On
A shallow copy creates a new object with the properties copied from the source. A deep copy creates a new object with properties that are themselves new objects based on the properties of the source.
If the source only contains primitive values, there won't be any difference between a shallow copy and a deep copy. The difference appears when the source contains properties that are collections or complex objects. Consider the following:
source = [['a', 'b', 'c']]
Here we have a source object that is an array which contains an array. If we perform a shallow copy, the new object will contain a reference to the same array:
target = copy.copy(source)
target[0][0] = 'd'
print(source)
print(target)
# Output:
# [['d', 'b', 'c']]
# [['d', 'b', 'c']]
As you see, the inner array of both source and target point to the same array. As such, anything you do in target will affect the contents of source and vice versa.
By contrast, a deep copy doesn't just copy references, it recursively copies values of the nested objects and collections:
target = copy.deepcopy(source)
target[0][0] = 'd'
print(source)
print(target)
# Output:
# [['a', 'b', 'c']]
# [['d', 'b', 'c']]
The contents if the inner array in target is no longer the same as the inner array in source. They are two different arrays that happen to contain the same items.
This doesn't just apply to arrays. Dictionaries, class objects, and other collections will behave similarly under copy and deepcopy.
On
Consider this simple program:
l = [[2], [4]]
lc = l.copy() # shallow copy
lc[0][0] = 1
print(lc) # [[1], [4]] no surprises here
print(l) # [[1], [4]] because shallow copy
so even though you modified only lc, values (lists) inside outer list still refer to same anonymous inner lists.
Would you use copy.deepcopy() instead to copy l to new list, then it would recursively copy values of any nested data structures, and modifying lc would not change the original list values in l
The deep copy will also copy nested containers. Perhaps the best way to demonstrate is by showing an example where the shallow copy is insufficient:
Now L3 is a shallow copy of L2. Modifications to L2 itself will not be mirrored:
However, modifications to the nested list L1 will be mirrored in both:
If we had used
copy.deepcopyinstead ofcopy.copywhen creating L3, then the nested list L1 would also have been copied. The result would be that L3 would still be[[]]in the final example, and L3 and L2 would be truly disconnected containers.