Skip to content

Python Shallow Copy and Deep Copy

Learn the difference between shallow and deep copies in Python, including how object references work and how to use the copy module to copy nested objects independently.

In Python, you can copy an object using either a Shallow Copy or a Deep Copy, depending on whether you want the copy to be independent of the original or not.

The Wrong Way to Copy an Object in Python

In Python, the = operator does not create a true copy of an object. Instead, it creates a new reference to the existing object!

To better understand this problem, consider this example in which a list named old_list is created and an object reference is passed to new_list using = operator:

old_list = [[1, 2, 3], [4, 5, 6], [7, 8, 'a']]
new_list = old_list

new_list[2][2] = 9

print('Old List:', old_list)
print('ID of Old List:', id(old_list))

print('New List:', new_list)
print('ID of New List:', id(new_list))

and the output is:

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

Notice that both variables old_list and new_list share the same ID (140673303268168), indicating that they both point to the same object in memory. This means that changes made to old_list and new_list are actually being made to the same object.

Types of Copy in Python

In Python, there are two ways to create copies:

  • Shallow Copy
  • Deep Copy

Shallow Copy

A Shallow Copy is a copy of an object that does not create a new instance of the object's nested objects, but references the same nested objects in the original.

This means that if you modify a nested object in the surface copy, the corresponding nested object in the original object will also be modified, because both the original and the copy refer to the same nested object.

For example, create a nested list, shallow copy it using copy() method and then do some changes:

import copy

old_list = [1,  2, [3,  5],  4]
new_list = copy.copy(old_list)

# Modifying the nested list in the shallow copy
new_list[2][0] =  7

# Original list is affected because the nested list is the same instance
print(old_list)  # Output: [1,  2, [7,  5],  4]
print(new_list)  # Output: [1,  2, [7,  5],  4]

Deep Copy

A Deep Copy consists of creating a new object and recursively inserting copies of the items found in the original object into it.

This process ensures that the new object is completely independent of the original one: any changes made to the deep copy will not affect the original object and vice versa.

For example, create a nested list, deep copy it using deepcopy() method and then do some changes:

import copy

old_list = [[1, 1, 1], [2, 2, 2], [3, 3, 3]]
new_list = copy.deepcopy(old_list)

# Modifying the nested list in the deep copy
new_list[2][0] =  0
new_list[2][1] =  0
new_list[2][2] =  0

print(old_list) # [[1, 1, 1], [2, 2, 2], [3, 3, 3]]
print(new_list) # [[1, 1, 1], [2, 2, 2], [0, 0, 0]]

Summary of the differences between Shallow Copy and Deep Copy

The main differences between a shallow copy and a deep copy in Python are:

  • Shallow Copy

    • Quickly duplicates the outer structure of the original object, but the inner objects are not copied; references to the original objects are kept instead.
    • Changes to the copied object's inner objects will affect the original object's inner objects, as they are pointing to the same memory location.
    • Generally faster than a deep copy because it does not need to duplicate the nested objects.
  • Shallow Copy:

    • Quickly duplicates the outer structure of the original object, but the inner objects are not copied; references to the original objects are kept instead.
    • Changes to the copied object's inner objects will affect the original object's inner objects, as they are pointing to the same memory location.
    • Generally faster than a deep copy because it does not need to duplicate the nested objects
Navigation