What is difference between shallow copy and deep copy in Python?

In Python, when working with objects and data structures, it is important to understand the concepts of shallow copy and deep copy. These techniques allow us to create copies of objects or data structures while preserving their integrity and avoiding unexpected side effects.

Shallow copy and deep copy
Shallow copy and deep copy

Understanding shallow copy

A shallow copy creates a new object or data structure and populates it with references to the original elements. In other words, it copies the references to the nested objects instead of creating new copies. Consequently, modifications made to the original object’s nested elements will also affect the shallow copy.

Shallow copy in Python

Python provides several ways to perform a shallow copy. Let’s explore some of the common techniques with code examples:

Using the copy() method:

import copy
original_list = [1, 2, 3]
shallow_copy = copy.copy(original_list)
print(shallow_copy)

Note: Shallow copy is equal to deep copy for simple lists.

The example above has created a shallow copy of a simple list. Now let's try to make changes to the shallow list. You will see that the content of the original list doesn't get changed.

import copy
original_list = [1, 2, 3]
shallow_copy = copy.copy(original_list)
print(shallow_copy)
## Making changes in shallow_copy list
shallow_copy[1]=44
print(shallow_copy)
print(original_list)

Now, let's try to make a shallow copy of a nested list. You will see that the changes made in the shallow copied list also get reflected in the original list and vice versa (changes made in the original list, get reflected in the shallow copied list).

import copy
original_list = [[1, 2, 3],[4,5,6]]
shallow_copy = copy.copy(original_list)
print(shallow_copy)
## Making changes in shallow_copy list
shallow_copy[1][2]=44
print(shallow_copy)
print(original_list)

Using the slice operator [:]:

Let's create a shallow copy list using the slice operator.

original_dict = [[1,2,3,4],[5,6,7,8]]
shallow_copy = original_dict[:]
print('Shallow_copy list')
print(shallow_copy)
print('\n')
original_dict[1][3]=55
print('After making changes in original list')
print('\n')
print('Shallow_copy list')
print(shallow_copy)

Understanding deep copy

A deep copy, on the other hand, creates a completely independent copy of the object or data structure. It recursively copies all the nested objects, ensuring that modifications made to the original object do not affect the deep copy.

Deep copy in Python

Python’s copy module provides the deepcopy() function to perform deep copies. Let’s see how it can be used:

import copy
original_list = [1, 2, [3, 4]]
deep_copy = copy.deepcopy(original_list)
print(deep_copy)

In the example above deepcopy() creates a new object that is a fully independent copy of the original list, including its nested elements. Now let's make changes in the nested deep copy. You will see that the original list content changes will not reflect the deep copy list content, and vice versa.

import copy
original_list = [1, 2, [3, 4]]
deep_copy = copy.deepcopy(original_list)
print(deep_copy)
original_list[2][1]=99
print('\n')
print("After making changes in original list")
print('\n')
print("Original list")
print(original_list)
print("Deep copy")
print(deep_copy)
deep_copy[2][0]=105
print('\n')
print("After making changes in deep copy")
print('\n')
print("Original list")
print(original_list)
print("Deep copy")
print(deep_copy)

Difference between shallow and deep copy

Now that we understand the basics of shallow copy and deep copy, let’s summarize their differences:

Difference

Shallow Copy

Deep Copy

Reference vs. Independent Copy

Copies references to nested objects

Creates independent copies of nested objects

Modifying the Copy

Changes made to the original object’s nested elements will reflect in the shallow copy.

Modifications made to the original object do not affect the deep copy.

Memory Consumption

Consumes less memory since it shares references.

Requires more memory since it creates completely independent copies.

Levels of Copying

Copies only the top-level object, not its nested elements

Recursively copies all nested objects

Choosing between shallow and deep Copy

The choice between shallow copy and deep copy depends on the specific requirements of your code. Here are some considerations:

  1. Shallow copy:

    1. Useful when you want to create a new object that shares references to the original object’s nested elements.

    2. Saves memory when dealing with large data structures.

    3. Offers performance benefits when you don’t need independent copies.

  2. Deep copy:

    1. Preferred when you need a completely independent copy of the original object, including its nested elements.

    2. Ensures that modifications to the original object do not affect the copy.

    3. Suitable for scenarios where you want to avoid unexpected side effects or when you need to modify the copy independently.

Conclusion

Shallow copy and deep copy are valuable techniques in Python for creating copies of objects or data structures. While shallow copy shares reference to nested elements, deep copy creates independent copies. Understanding their differences is important for managing object integrity and avoiding unexpected side effects.

Copyright ©2024 Educative, Inc. All rights reserved