Shallow Copy and Deep Copy in Python

In this article, we will see what is Shallow Copy and Deep Copy, with the help of some code examples and we will also see what is difference between them.

Copy an Object in Python

To make a copy of an object in Python, use the = operator. You would suppose that this produces a new object, but it does not. It just generates a new variable that shares the original object’s reference.

Let’s take an example where we create a list named list1 which is the old one and pass an object reference to list2 which is a new one using the = operator.

list1 = [['a', 8, 7], [6, 5, 4], [3, 2, 1]]
list2 = list1
list2[0][0] = 9
print('Old List:', list1)
print('ID of Old List:', id(list1))
print('New List:', list2)
print('ID of New List:', id(list2))

Output:

Old List: [[9, 8, 7], [6, 5, 4], [3, 2, 1]]
ID of Old List: 140647864687232
New List: [[9, 8, 7], [6, 5, 4], [3, 2, 1]]
ID of New List: 140647864687232

As shown in the result, both variables list1 and list2 have the same id, 140647864687232. So, if you change any values in either list1 or list2, the change is reflected in both.

Copy Module

Essentially, sometimes you may want to have the original values unchanged and only modify the new values or vice versa. In Python, there are two ways to create copies.

  1. Shallow Copy
  2. Deep Copy

To make these copy work, we use the copy module.

Example: We use the copy module of Python for shallow and deep copy operations. Suppose, you need to copy the compound list say a.

import copy
copy.copy(a)
copy.deepcopy(a)

Here, copy() returns a shallow copy of a. Similarly, deepcopy() returns a deep copy of a.

Shallow Copy

A shallow copy creates a new object that keeps the references of the original elements. As a result, a shallow copy does not create a duplicate of nested objects; rather, it copies the reference to nested objects. This means that a copy operation does not recurse or produce duplicates of nested objects.

Code Example 01:

import copy
list1 = [[9, 8, 7], [6, 5, 4], [3, 2, 1]]
list2 = copy.copy(list1)
print("Old list:", list1)
print("New list:", list2)

Output:

Old list: [[9, 8, 7], [6, 5, 4], [3, 2, 1]]
New list: [[9, 8, 7], [6, 5, 4], [3, 2, 1]]

In the above program, we created a nested list and then shallow copied it with the copy() function. This means that it will generate a new, independent object with the same content. We print both list1 and list2 to confirm this.

To confirm that list2 differs from list1, we create a new nested object to the original and test it.

Code Example 02: Adding [10, 11, 12] to list2, using shallow copy.

import copy
list1 = [[9, 8, 7], [6, 5, 4], [3, 2, 1]]
list2 = copy.copy(list1)
list1.append([10, 11, 12])
print("Old list:", list1)
print("New list:", list2)

Output:

Old list: [[9, 8, 7], [6, 5, 4], [3, 2, 1], [10, 11, 12]]
New list: [[9, 8, 7], [6, 5, 4], [3, 2, 1]]

In the above program, we made a shallow copy of the list1. The list2 contains references to the old list’s original nested objects. Then we insert the new list, [10, 11, 12], into an old list. This newly created sublist was not duplicated into a new list.

When you change any nested items in the old list, the changes are reflected in the new list.

Code Example 03: Adding new nested object using Shallow copy

import copy
list1 = [[9, 8, 7], [6, 5, 4], [3, 2, 1]]
list2 = copy.copy(list1)
list1[1][1] = 10
print("Old list:", list1)
print("New list:", list2)

Output:

Old list: [[9, 8, 7], [6, 10, 4], [3, 2, 1]]
New list: [[9, 8, 7], [6, 10, 4], [3, 2, 1]]

In the above program, we changed list1 to list1[1][1] = 10. Both old list and new list sublists at index [1][1] were updated. This is due to the fact that both lists include references to the same nested objects.

Deep Copy

A deep copy creates a new object and adds copies of nested objects existing in the original elements recursively.

Let’s move on to the copy module example. However, we will make a deep copy by utilizing the deepcopy() method from the copy module. Deep copy makes an independent duplicate of the original object and all of its nested objects.

Code Example 01: Copying a list using deepcopy()

import copy
list1 = [[9, 8, 7], [6, 5, 4], [3, 2, 1]]
list2 = copy.deepcopy(list1)
print("Old list:", list1)
print("New list:", list2)

Output:

Old list: [[9, 8, 7], [6, 5, 4], [3, 2, 1]]
New list: [[9, 8, 7], [6, 5, 4], [3, 2, 1]]

In the above program, we utilize the deepcopy() method to make a copy that is comparable to the original.

If you make changes to any nested objects in the original object’s old list, the copy new list will not change.

Code Example 02: Adding a new nested object in the list using a Deep copy

import copy
list1 = [[9, 8, 7], [6, 5, 4], [3, 2, 1]]
list2 = copy.deepcopy(list1)
list1[1][1] = 10
print("Old list:", list1)
print("New list:", list2)

Output:

Old list: [[9, 8, 7], [6, 10, 4], [3, 2, 1]]
New list: [[9, 8, 7], [6, 5, 4], [3, 2, 1]]

When we set a new value to list1 in the above program, we can observe that only the old list is affected. This signifies that the old list and the new list are distinct. This is due to the fact that the old list was recursively copied, as were all of its sub-items.

Shallow Copy vs Deep Copy

Shallow CopyDeep Copy
Shallow Copy stores the references of objects to the original memory address.Deep copy stores copies of the object’s value.
It reflects changes made to the new/copied object in the original object.It copy doesn’t reflect changes made to the new/copied object in the original object.
Shallow Copy stores the copy of the original object and points the references to the objects.Deep copy stores the copy of the original object and recursively copies the objects as well.
It is fasterIt is comparatively slower.

Conclusion

That’s all for this article, if you have any confusion contact us through our website or email us at [email protected] or by using LinkedIn

Suggested Articles:

  1. The NumPy copyto Python Function

Leave a Comment