- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Difference between Shallow and Deep Copy of a Class
A class is a blueprint or template that defines objects' attributes (data) and behaviours (methods). It's by far a fundamental concept of object-orientated programming (OOP) that allows you to create items based totally on the class definition.
Shallow copy
Shallow copy creates a new object that stores the reference of the original elements. Instead of making a duplicate of the nested objects, it just replicates their references. This means that a copy process does not recurse or create copies of nested objects itself. Shallow copy is faster than deep copy, but it is "lazy" and handles pointers and references.
It just replicates the pointer price rather than making a modern duplicate of the specific information the pointer links to. So, both the original and the copy will have pointers that reference constant underlying knowledge.
Shallow copy is often performed using the built-in copy.copy() method or the copy constructor.
Deep Copy
A deep copy creates a new object that stores copies of the original elements. It is not shared between the original and the copy. Deep copy actually clones the underlying data. It is not shared between the original and the copy. Deep copy is slower than shallow copy, but it creates a complete copy of the object and all of its children.
A deep copy can be achieved using the copy.deepcopy() method provided by the copy module.
Example
In this example, we will create an instance of a class and make its shallow and deep copy to understand how the copying process works and how it affects the memory addresses of the internal objects.
import copy class MyClass: def __init__(self, name, numbers): self.name = name self.numbers = numbers def __repr__(self): return f"MyClass(name='{self.name}', numbers={self.numbers})" # Creating an instance of MyClass original_obj = MyClass("Rahul Ravindranath", [53, 27, 82]) print("Memory address of original_obj.name:", id(original_obj.name)) print("Memory address of original_obj.numbers:", id(original_obj.numbers)) # Making a shallow copy shallow_copy = copy.copy(original_obj) # Checking memory addresses of internal objects for shallow copy print("Memory address of shallow_copy.name:", id(shallow_copy.name)) print("Memory address of shallow_copy.numbers:", id(shallow_copy.numbers)) # Creating a Deep copy deep_copy = copy.deepcopy(original_obj) # Checking memory addresses of internal objects for deep copy print("Memory address of deep_copy.name:", id(deep_copy.name)) print("Memory address of deep_copy.numbers:", id(deep_copy.numbers))
Output
Memory address of original_obj.name: 23317216835824 Memory address of original_obj.numbers: 23317215777984 Memory address of shallow_copy.name: 23317216835824 Memory address of shallow_copy.numbers: 23317215777984 Memory address of deep_copy.name: 23317216835824 Memory address of deep_copy.numbers: 23317215706944
It is to be noted that the memory address varies for different devices.
From the above outputs, we infer that the memory addresses of shallow_copy.name and shallow_copy.numbers are the same as the memory addresses of the corresponding attributes in original_obj. This indicates that the internal objects are not duplicated but are referenced.
When we check the memory addresses of deep_copy.name and deep_copy.numbers, we find that they are different from the memory addresses of the corresponding attributes in original_obj. This shows that the internal objects have been duplicated, creating separate instances for deep_copy.
Example
In this code, we will create a class and make its shallow and deep copy then modify the copies with some operations and demonstrate the changes in the original and its copies.
Algorithm
Define a class named ClassEx with an __init__ method that initializes an instance with a name attribute and an empty list attribute.
Implement an add_item and __str__ method to append items to the list and provide a string representation of the instance.
Create an instance of ClassEx named original
Using add_item method append the required data to the original and its copies
Display the “original” instance and the shallow and deep copy
With the use of a list attribute and indexing replace some items in each object which includes original, shallow copy and deep copy.
Print the updated original object, shallow_copy, and deep_copy.
import copy class ClassEx: def __init__(self, name): self.name = name self.list = [] def add_item(self, item): self.list.append(item) def __str__(self): return f"{self.name}: {self.list}" # Create an instance of ClassEx original = ClassEx("Original") # Add some items to the list original.add_item("Item 1") original.add_item("Item 2") # Create a shallow copy of the object shallow_copy = copy.copy(original) # Add an item to the list of the shallow copy shallow_copy.add_item("Item 3") # Print the original object and the shallow copy print("Original object:", original) print("Shallow copy:", shallow_copy) # Create a deep copy of the object deep_copy = copy.deepcopy(original) # Add an item to the list of the deep copy deep_copy.add_item("Item 4") # Print the original object and the deep copy print("Original object:", original) print("Deep copy:", deep_copy) # Replace an item in the original object original.list[0] = "New Item 1" # Replace an item in the shallow copy shallow_copy.list[1] = "New Item 2" # Replace an item in the deep copy deep_copy.list[2] = "New Item 3" # Print the updated objects print("Original object:", original) print("Shallow copy:", shallow_copy) print("Deep copy:", deep_copy)
Output
Original object: Original: ['Item 1', 'Item 2', 'Item 3'] Shallow copy: Original: ['Item 1', 'Item 2', 'Item 3'] Original object: Original: ['Item 1', 'Item 2', 'Item 3'] Deep copy: Original: ['Item 1', 'Item 2', 'Item 3', 'Item 4'] Original object: Original: ['New Item 1', 'New Item 2', 'Item 3'] Shallow copy: Original: ['New Item 1', 'New Item 2', 'Item 3'] Deep copy: Original: ['Item 1', 'Item 2', 'New Item 3', 'Item 4']
The shallow copy shares the internal objects with the original, while the deep copy creates independent copies of the internal objects. Changes made in shallow copy and original object affect each other while the deep copy is completely separate and doesn't affect the original object when modifications are done in deep copy.
Key Differences
Shallow Copy | Deep Copy | |
---|---|---|
Memory Sharing | Shares memory locations with the original object | Creates an independent copy with separate memory locations |
Performance | Faster and more efficient, especially for large objects or complex data structures | Slower and may consume more memory, particularly for large objects or deep nesting |
Data Integrity | May lead to unintended modifications of the original object | Ensures data integrity by isolating the copied object |
Changes to Copied Object | Modifications can affect the original object and vice versa | Modifications do not affect the original object |
Dependencies and References | Shared references can cause unintended side effects or data integrity issues | Handles circular references and complex interdependencies by copying all nested objects |
Conclusion
A shallow copy is used to Create a backup or snapshot of an object's current state. It is preferred when Implementing copy-on-write behaviour, where a copy is only made when changes are made to the copied object and for creating a new object with initial values based on an existing object.
Deep copy is used when we want to Create a completely independent copy of an object and its nested objects. It is helpful in the Serialization and deserialization of objects, where the copied object needs to be stored or transmitted independently.