github icon
github icon
avatar

shafikshaon / Understanding Deep Copy and Shallow Copy in Python: A Guide for Beginners

Created Wed, 07 Dec 2022 23:15:09 +0600 Modified Sun, 25 Feb 2024 20:22:56 +0000
605 Words 3 min

Shallow Copy and Deep Copy

In this article, we will learn about shallow copy and deep copy in Python.

In Python, we use the assignment (=) operator to create a copy of an object. However, it doesn’t make a new object. Instead, it just shares the reference of the original object to a new variable. In the following example, the old_list hold value [1, 2, 3] and assing to new variable named new_list by using assignment(=) operator. If we modify the new_list, the old_list will also be affected. You can also see that the old_list and new_list id are the same, i.e., 4350750272.

>>> old_list = [1, 2, 3]
>>> new_list = old_list
>>> new_list[2] = 0
>>> print(old_list)
[1, 2, 0]
>>> print(new_list)
[1, 2, 0]
>>> print(f"id of new_list {id(new_list)}, id of old_list {id(old_list)}")
id of new_list 4350750272, id of old_list 4350750272

Why do we need a deep copy or a shallow copy?

Sometimes we need to keep original values unchanged and only modified in the new ones or vice versa. In Python, we have two ways to do this.

  1. Shallow copy
  2. Deep copy

Python copy Module

Python has a copy module for the deep and shallow copy.

copy.copy(x) Return a shallow copy of x.

copy.deepcopy(x) Return a deep copy of x.

exception copy.Error Raised for module-specific errors.

Shallow Copy

A shallow copy creates new objects that store the original objects’ reference. A shallow copy doesn’t create a copy of nested objects where, as it only copies the reference of the nested objects. [1]

Create a copy using shallow copy

>>> import copy
>>> old_list = [[1, 2], [3, 4]]
>>> new_list = copy.copy(old_list)
>>> print(old_list)
[[1, 2], [3, 4]]
>>> print(new_list)
[[1, 2], [3, 4]]

In the above example, we create a nested list and shallow copy the value to another variable named new_list using the copy method, it will create independent objects with the same content. Now we add some data in old_list.

>>> old_list.append([5,6])
>>> print(old_list)
[[1, 2], [3, 4], [5, 6]]
>>> print(new_list)
[[1, 2], [3, 4]]

Here, we append new list [5, 6] to old_list. The new_list contains references of original nested objects stored in old_list. The new sublist [5, 6] was not copied in new_list. But, if you change any nested objects in the old_list, the changes also reflect in the new_list because both lists share the reference of the same nested objects.

>>> old_list[1][1] = 'X'
>>> print(old_list)
[[1, 2], [3, 'X'], [5, 6]]
>>> print(new_list)
[[1, 2], [3, 'X']]

Deep Copy

A deep copy creates a new object and recursively adds the copies of nested objects present in the original elements. [1]

Create a copy using deep copy

>>> import copy  
>>> old_list = [[1, 2], [3, 4]]  
>>> new_list = copy.deepcopy(old_list)  
>>> print(old_list)  
[[1, 2], [3, 4]]  
>>> print(new_list)  
[[1, 2], [3, 4]]  

If any changes to nested objects of the old_list, the changes are not reflected in new_list.

>>> import copy
>>> old_list = [[1, 2], [3, 4]]
>>> new_list = copy.deepcopy(old_list)  
>>> old_list[1][1] = 'X'
>>> print(old_list)
[[1, 2], [3, 'X']]
>>> print(new_list)
[[1, 2], [3, 4]]

What is the Difference Between Deep and Shallow Copies? [2]

The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):

  • A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

  • A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

References:

[1] https://www.programiz.com/python-programming/shallow-deep-copy

[2] https://docs.python.org/3/library/copy.html

Commit ID: c5d17ea267e3042c327c7fa17af122cf4c614f7b ∙ View Commit on GitHub