To clone an object, Python offers us a special function that every programmer should learn about. So, we are diving into what is a deep copy in python? Why do we need it? Some examples to understand it better and what are its major applications.
What is Deep Copy in Python?
When coding in python we often create copies using the assignment operator “=“. It only creates a new variable that shares the reference of the original object. This doesn’t make a difference for an immutable object but when it comes to mutable objects it fails to make a true clone or copy.
The copying of these objects can be done via the copy module present in python. The copy module in Python provides functions for creating copies of objects. It includes both a copy() function for creating shallow copies, and a deepcopy() function for creating deep copies.
A shallow copy is a copy of an object that is not a completely independent copy of the original object. Instead, a shallow copy only creates a new object with a new reference to the same underlying object as the original object.
It will create a new object with a new reference to the same underlying objects as the original object, but it will not recursively copy all objects and attributes, including nested objects and lists.
A deep copy in python is a copy of an object that is completely independent of the original object. It means that any changes made to the copied object do not affect the original object and vice versa.
The deepcopy() function will create a deep copy of any object, including custom objects and classes. It will recursively copy all objects and attributes, including nested objects and lists so that the copied object is completely independent of the original object.
Syntax of Deep Copy in Python
We need to import copy module first. There are 2 functions that can be used with this module: copy() and deepcopy(). Copy( ) will return a shallow copy, deepcopy() will return a deep copy of the object. Here is how to make a copy:
To return shallow copy:
copy.copy(x)
To return deep copy in python:
Copy.deepcopy(x)
As you can see, the syntax for deep copy in Python is slightly different but also very easy to implement.
Examples of Deep Copy
Let us understand better by taking an example of a nested list and seeing the various results. We will take a nested list: List_A = [a , b,[ c, d ], e , f , g , [h,i]].
First, we will use the generic assignment operator to create copies.
list_A = [ 'a', 'b',[ 'c', 'd' ], 'e' , 'f' , 'g' , ['h','i']] list_B = list_A print(list_A) print(list_B) #Let us check the id of both the objects print(id(list_A)) print(id(list_B))
Output:
[ 'a', 'b',[ 'c', 'd' ], 'e' , 'f' , 'g' , ['h','i']] [ 'a', 'b',[ 'c', 'd' ], 'e' , 'f' , 'g' , [‘h','i']] 4578625920 4578625920
We can see that the same id is shared by both objects hence any changes made will be reflected in both objects, i.e they are not separate identities.
Let us make a shallow copy of the same list.
import copy list_A = [ 'a', 'b',[ 'c', 'd' ], 'e' , 'f' , 'g' , ['h','i']] list_B = copy.copy(list_A) print(list_A) print(list_B)
Output:
['a', 'b', ['c', 'd'], 'e', 'f', 'g', ['h', 'i']] ['a', 'b', ['c', 'd'], 'e', 'f', 'g', ['h', ‘i']]
Let us understand how the copy() function works by appending the original list I.e list_A.
import copy list_A = [ 'a', 'b',[ 'c', 'd' ], 'e' , 'f' , 'g' , ['h','i']] list_B = copy.copy(list_A) list_A.append(["a","b"]) print(list_A) print(list_B)
Output:
['a', 'b', ['c', 'd'], 'e', 'f', 'g', ['h', 'i'], ['a', 'b']] ['a', 'b', ['c', 'd'], 'e', 'f', 'g', ['h', 'i']]
We can see when we appended the list_A has been appended but no changes are made to list_B.
Let us now assign a new value to the nested values within list_A.
import copy list_A = [ 'a', 'b',[ 'c', 'd' ], 'e' , 'f' , 'g' , ['h','i']] list_B = copy.copy(list_A) list_A[2][1] = "c" print(list_A) print(list_B)
Output:
['a', 'b', ['c', 'c'], 'e', 'f', 'g', ['h', 'i']] ['a', 'b', ['c', 'c'], 'e', 'f', 'g', ['h', ‘i']]
Here we can see that the result is changed in both lists, this is because shallow copy shares the same reference In nested values.
Now let us try to make a deep copy of the same list_A.
import copy list_A = [ 'a', 'b',[ 'c', 'd' ], 'e' , 'f' , 'g' , ['h','i']] list_B = copy.deepcopy(list_A) print(list_A) print(list_B)
Output:
['a', 'b', ['c', 'd'], 'e', 'f', 'g', ['h', 'i']] ['a', 'b', ['c', 'd'], 'e', 'f', 'g', ['h', 'i']]
Let us perform the same operations appending and reassigning nested values of the list. We will now append the list as we did before.
import copy list_A = [ 'a', 'b',[ 'c', 'd' ], 'e' , 'f' , 'g' , ['h','i']] list_B = copy.deepcopy(list_A) list_A.append(["a"]) print(list_A) print(list_B)
Output:
['a', 'b', ['c', 'd'], 'e', 'f', 'g', ['h', 'i'], ['a']] ['a', 'b', ['c', 'd'], 'e', 'f', 'g', ['h', ‘i']]
We can see that only list_A is appended and list_B remains the same. But what if we reassign nested values?
import copy list_A = [ 'a', 'b',[ 'c', 'd' ], 'e' , 'f' , 'g' , ['h','i']] list_B = copy.deepcopy(list_A) list_A[2][1] = "c" print(list_A) print(list_B)
Output:
['a', 'b', ['c', 'c'], 'e', 'f', 'g', ['h', 'i']] ['a', 'b', ['c', 'd'], 'e', 'f', 'g', ['h', ‘i’]]
We can see that only list_A is changed and list_B remains the same.
Applications of Deep Copy
Deepcopy can be useful in various fields. Deep Copy in Python can be used for creating a copy of an object that can be modified without affecting the original object. This applies to creating independent copies of objects as well.
If you have an object that you want to modify, but you want to keep the original object unchanged, you can use a deep copy to create a new object that is a copy of the original. It allows you to change a copy without altering the original data.
It can also be used to preserve the state of an object. If you have an object that represents the state of a system, you may want to make a deep copy of it at certain points in time to preserve its state. This can be useful for debugging or for creating a history of the object's state.
One more use case of deep is that if you have a complex object with multiple references to other objects, making a shallow copy of the object may not be sufficient to create a completely independent copy. In this case, a deep copy can be used to ensure that the copy is completely independent of the original object.
Conclusion
So, now you got a thorough understanding of Deep Copy in Python and how it is different from assignment operator and shallow copy with the help of the examples.