Register Login

Deep copy vs. shallow copy

Copying an object in Python is a basic feature that every programmer uses while working with classes and objects (Object Oriented Programming) in Python. Copying objects can be categorized into two different types. In this article, you will learn about these two topics and how they are practically used.

Copying an Object in Python:

Copying an object means creating a duplicate of the original object. usually, programmers use the assignment operator (=) for creating a copy of an object. Most programmers think of it as a new object, but it isn't. It only generates a new variable, which is sharing the original object's reference.

Program:

oldli = [[3, 6, 9], [2, 4, 6], ['a', 'b', 'c']]
newli = oldli
newli[2][2] = 10
print('Old List object is:', oldli)
print('The ID of old list is:', id(oldli))
print('New List object is :', newli)
print('The ID of New List is:', id(newli))

Output:

Old List object is: [[3, 6, 9], [2, 4, 6], ['a', 'b', 10]]
The ID of old list is: 2048496598272
New List object is : [[3, 6, 9], [2, 4, 6], ['a', 'b', 10]]
The ID of New List is: 2048496598272

Explanation:

Here we have taken two variables, oldli and newli and assigned oldli with a nested list. Then we assign newli with the values of oldli. Now, we are changing the newli’s [2][2] location. This will also impact the oldli object and will replace the element at that position (‘c’) with 10. Finally, we use the print to display the id of the objects as well as their values.

What are Shallow Copy and Deep Copy?

Naturally, sometimes programmers wish to produce an object keeping the original value unchanged; and modify the new values only or vice versa. Note that shallow copy and the deep copy can be implemented only with the collection type variables. Also, the connections that will use deep copy or shallow copy must have this mutability feature as well. In both the cases, we will use the copy module. In Python, programmers can create copies using two different approaches:

Shallow Copy:

A shallow copy helps in creating a new object where it stores the original element's reference. Shallow repetition is faster in this case. But the process is lazy. That means it points to a location via reference. Instead of producing a simultaneous copy of the distinct object, it simply copies the reference of the objects. Here, we will use the copy() method.

Program:

import copy
oldli = [[2, 4, 6], [3, 6, 9], ['a', 'b', 'c']]
newli = copy.copy(oldli)
print(" Old list is:", oldli)
print(" New list is:", newli)
newli[2][2] = 10
print(" Old list is:", oldli)
print(" New list is:", newli)

Output:

Old list is: [[2, 4, 6], [3, 6, 9], ['a', 'b', 'c']]
New list is: [[2, 4, 6], [3, 6, 9], ['a', 'b', 'c']]
Old list is: [[2, 4, 6], [3, 6, 9], ['a', 'b', 10]]
New list is: [[2, 4, 6], [3, 6, 9], ['a', 'b', 10]]

Explanation:

Here we have to import the copy module. Next, we have created a nested list. We have assigned the new list with the copy() method and passed the old list within it as the parameter. Then, we use the print() function to display both the old and the new list. Next, we make changes in the new list to see if it changes the old list or not. Finally we use the print() function again to display both the lists. You can see both lists get impacted because of the change.

Deep Copy:

A deep copy helps in creating a new object and recursively appends the copies of nested objects existing in the original object/elements. It stores the object value and not the reference. Here we will use the deepcopy() method.

Program:

import copy
oldli = [[2, 4, 6], [3, 6, 9], ['a', 'b', 'c']]
newli = copy.deepcopy(oldli)
print(" Old list is:", oldli)
print(" New list is:", newli)
newli[2][2] = 10
print(" Old list is:", oldli)
print(" New list is:", newli)

Output:

Old list is: [[2, 4, 6], [3, 6, 9], ['a', 'b', 'c']]
New list is: [[2, 4, 6], [3, 6, 9], ['a', 'b', 'c']]
Old list is: [[2, 4, 6], [3, 6, 9], ['a', 'b', 'c']]
New list is: [[2, 4, 6], [3, 6, 9], ['a', 'b', 10]]

Explanation:

Here we have to import the copy module. Next, we have created a nested list. We have assigned the new list with the deepcopy() method and passed the old list within it as the parameter. Then, we use the print() function to display both the old and the new list. Next, we make changes in the new list to see if it changes the old list or not. Finally we use the print() function again to display both the lists. You can see the second list do not get impacted because of the change. 

Difference between Shallow Copy and Deep Copy:

Shallow Copy Deep Copy
In shallow copy, the reference to the object of the original memory's address is stored. In deep copy, the value of the original object is stored.
Shallow copy is comparatively faster than the deep copy. Deep copy is comparatively slower than the shallow copy.
All the changes get reflected in the shallow copy when changes are made to the new or copied object. No changes get reflected in the case of deep copy when changes are made to the new or copied object.
Shallow copy points to the reference of the object. Deep copy saves the copy of the original object while recursively coping the objects also.
We can implement the shallow copy using the copy() method. We will implement the deep copy using the deepcopy() method.
Shallow copy duplicate as little as possible. Deep copy duplicate as much as possible.

Conclusion:

If you consider time-complexity into your program, then it is always beneficial to go with shallow copy rather than deep copy. Again, if you want to create a separate copy of both and work on any one of them without tempering the other, deep copy works best in this case. It is up to the programmer or developer and their situation that will compel them to choose between these two.