Python Copy – Perform Deep and Shallow Copy

Python Copy Module

In this article, we’ll be looking at using the Python Copy module, to perform deep and shallow copy operations.

Now, what do we mean by deep copy and shallow copy?

Let’s take a look, using illustrative examples!


Why do we need the Python Copy module?

In Python, everything is represented using objects. Therefore, in a lot of cases, we may need to copy objects directly.

In these cases, we cannot use the assignment operator directly.

The point behind assignment is that multiple variables can point to the same object. This means that if the object changes using any of those variables, changes will be reflected everywhere!

The following example illustrates this problem, using a shared list object, which is mutable.

a = [1, 2, 3, 4]

b = a

print(a)
print(b)

b.append(5)

# Changes will be reflected in a too!
print(a)
print(b)

Output

[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]

As you can see, since both variables point to the same object, when b changes, so does a!

To deal with this issue, Python gives us a way using the Copy module.

The Python copy module is a part of the standard library, and can be imported using the below statement:

import copy

Now, in this module, we can perform two types of operations mainly:

  • Shallow Copy
  • Deep Copy

Let’s take a look at these methods now.


Shallow Copy

This method is used to perform a shallow copy operation.

The syntax for calling this method is:

import copy

new_obj = copy.copy(old_obj) # Perform a shallow copy

This will do two things –

  • Create a new object
  • Insert all references of the objects found in the original object

Now, since it creates a new object, we can be sure that our new object is different from the old object.

However, this will still maintain references to nested objects. So if the object we need to copy has other mutable objects (list, set, etc), this will still maintain references to the same nested object!

To understand this, let’s take an example.

To illustrate the first point, we will try this with a simple list of integers (no nested objects!)

import copy

old_list = [1, 2, 3]

print(old_list)

new_list = copy.copy(old_list)

# Let's try changing new_list
new_list.append(4)

# Changes will not be reflected in the original list, since the objects are different
print(old_list)
print(new_list)

Output

[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3]

As you can see, in case our object is a simple list, there is no problem with shallow copy.

Let’s take another case, where our object is a list of lists.

import copy

old_list = [[1, 2], [1, 2, 3]]

print(old_list)

new_list = copy.copy(old_list)

# Let's try changing a nested object inside the list
new_list[1].append(4)

# Changes will be reflected in the original list, since the object contains a nested object
print(old_list)
print(new_list)

Output

[[1, 2], [1, 2, 3]]
[[1, 2], [1, 2, 3, 4]]
[[1, 2], [1, 2, 3, 4]]

Here, notice that both old_list and new_list have been affected!

If we must avoid this behavior, we must copy all objects recursively, along with nested objects.

This is called a Deep Copy Operation using the Python copy module.


Deep Copy

This method is similar to the shallow copy method, but now copies everything from the original object (including nested objects) into a new object.

To do a deep copy operation, we can use the below syntax:

import copy

new_object = copy.deepcopy(old_object)

Let’s take our old example, and try using deep copy to solve our issue.

import copy

old_list = [[1, 2], [1, 2, 3]]

print(old_list)

new_list = copy.deepcopy(old_list)

# Let's try changing a nested object inside the list
new_list[1].append(4)

# Changes will be reflected in the original list, since the objects are different
print(old_list)
print(new_list)

Output

[[1, 2], [1, 2, 3]]
[[1, 2], [1, 2, 3]]
[[1, 2], [1, 2, 3, 4]]

Notice that the old list is unchanged. Since all objects were copied recursively, there is no problem now!

However, due to copying all objects, this deepcopy method is a bit more expensive, as compared to the shallow copy method.

So use this wisely, only when you need it!


Conclusion

In this article, we learned about using the Python Copy module, to perform shallow copy and deep copy operations.

References

  • Python Copy Module Documentation
  • JournalDev article on Python Copy Module