Python: Deep and Shallow Copy Object

Introduction

In this article, we'll take a look at how to deep and shallow copy the objects in Python.

The short answer is that you can use methods of the copy module, for both operations:

import copy

shallow_copy_list = copy.copy(original_list)
deepcopy_list = copy.deepcopy(original_list)

Though, what does it mean to copy something in a shallow or deep fashion?

In the proceeding sections, we'll dive into what these terms mean, how Python treats object references and objects in memory, and why these two methods work the way they do.

Shallow Copy an Object in Python

When we use assignment statements (=) in Python to create copies of compound objects, such as lists or class instances or basically any objects that contain some other objects, Python does not clone the object itself. Instead, it simply binds the reference to the targeted object.

Imagine that we have a list with the following elements in it:

original_list =[[1,2,3], [4,5,6], ["X", "Y", "Z"]]

If we try to copy our original list using the assignment statement as follows:

shallow_copy_list = original_list
print(shallow_copy_list)

It may look like that we cloned our object and now have two of them:

[[1,2,3], [4,5,6], ['X', 'Y', 'Z']]

But, do we really have two objects? No, we don't. We have two reference variables pointing to the same object in memory. This can easily be verified by printing the ID of the object in memory for both of these:

id(original_list) # 4517445712
id(shallow_copy_list) # 4517445712

A more tangible proof of this can be observed by attempting to change a value in either of "the two lists" - while in reality, we change the same list, and both pointers point to the same object in memory.

Let's access the last element of the object pointed to by original_list:

# Last element of last element
original_list[-1][-1] = "ZZZ"
print(original_list)

This results in:

[[1, 2, 3], [4, 5, 6], ['X', 'Y', 'ZZZ']]

Knowing that both reference variables point to the same object, printing shallow_copy_list will return the same result:

print(shallow_copy_list)
[[1, 2, 3], [4, 5, 6], ['X', 'Y', 'ZZZ']]

Shallow Copying is the process of copying a reference to an object and storing it in a new variable. The original_list and shallow_copy_list are merely references that point to the same addresses in memory (RAM), that store the values of [[1, 2, 3], [4, 5, 6], ['X', 'Y', 'ZZZ']].

It is also possible to create a shallow copy of an object using a slice of the entire list and assignment statement:

slice_shallow_copy_list = original_list[:]

Another way to shallow copy is to use the copy module of Python’s standard library.

To use the copy module, we must first import it:

import copy

Now we can use the copy() method of the copy module:

Free eBook: Git Essentials

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

second_shallow_copy_list = copy.copy(original_list)

Print them both to see that if they reference the same values:

print(original_list)
print(second_shallow_copy_list)

As expected, they do:

[[1, 2, 3], [4, 5, 6], ['X', 'Y', 'ZZZ']]
[[1, 2, 3], [4, 5, 6], ['X', 'Y', 'ZZZ']]

Usually, you would want to copy a compound object, for example at the beginning of a method, then modify the clone, but keep the original object as it was in order to use it again later sometime.

To achieve this, we need to deep copy the object. Now let's learn what is a deep copy and how to deep copy a compound object.

Deep Copy an Object in Python

Deep copying an object means really cloning the object and its values into a new copy (instance) in memory, with those same values.

Rather than creating a new reference to the same values, with the deep copy, we can actually create a new object that is independent of the original data but contains the same values.

In a typical deep copy process, first, a new object reference is created, then all the child objects are added to the parent object recursively.

This way, unlike a shallow copy, making any modification to the original object, does not reflect in the copy object (or vice versa).

Here is a simple illustration of a typical deep copy:

To deep copy an object in Python, we use the deepcopy() method of the copy module.

Let's import the copy module and create a deep copy of a list:

import copy
 
original_list = [[1,2,3], [4,5,6], ["X", "Y", "Z"]]
deepcopy_list = copy.deepcopy(original_list)

Now let's print our lists to make sure the outputs are the same, as well as their IDs as proof of their uniqueness:

print(id(original_list), original_list)
print(id(deepcopy_list), deepcopy_list)

The output confirms that we've created ourselves a genuine copy:

4517599280, [[1, 2, 3], [4, 5, 6], ['X', 'Y', 'Z']]
4517599424, [[1, 2, 3], [4, 5, 6], ['X', 'Y', 'Z']]

Now let's try to modify our original list by changing the last element of the last list to the "O", and then print it to see the result:

original_list[-1][-1] = "O"
print(original_list)

We get the results as expected:

[[1, 2, 3], [4, 5, 6], ['X', 'Y', 'O']]

Now if we go ahead and try to print our copy list:

print(deepcopy_list)

The previous modification did not reflect on this list:

[[1, 2, 3], [4, 5, 6], ['X', 'Y', 'Z']]

Remember that the copy() and deepcopy() methods are applicable on other compound objects. This means that you can use them to create copies of class instances as well.

Conclusion

In this article, we learned what it means to shallow copy and to deep copy an object.

We also learned that we can use the copy() method of the copy module to create a shallow copy, and the deepcopy() method to create a deep copy of the compound objects.

Last Updated: September 27th, 2021
Was this article helpful?

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

Ruslan HasanovAuthor

Full-stack software developer.
Python, C#, Linux.

© 2013-2024 Stack Abuse. All rights reserved.

AboutDisclosurePrivacyTerms