Last modified: Feb 10, 2026 By Alexander Williams
Python Clone Object Guide: Deep vs Shallow Copy
Cloning objects is a fundamental skill in Python. It prevents bugs caused by unintended data sharing.
This guide explains the difference between copying and cloning. You will learn when and how to create independent duplicates of your data.
Why Clone Objects in Python?
In Python, assignment does not create a new object. It creates a new reference to the same object.
This means modifying one variable can change another. Cloning creates a separate, independent copy.
Understanding this is crucial for working with mutable objects like lists and dictionaries. For a deeper dive into how objects store data, see our Python Object Attributes Guide for Beginners.
# Assignment creates a reference, not a copy
original_list = [1, 2, 3]
reference_list = original_list # This is a reference
reference_list.append(4)
print("Original List:", original_list)
print("Reference List:", reference_list)
Original List: [1, 2, 3, 4]
Reference List: [1, 2, 3, 4]
Both variables point to the same list. Changing one affects the other. This is often not the desired behavior.
Shallow Copy: The copy() Method
A shallow copy creates a new outer object. However, it inserts references to the objects found in the original.
It is suitable for one-level-deep structures. Use the copy module's copy() function or an object's .copy() method.
import copy
original = [1, 2, [3, 4]]
shallow_clone = copy.copy(original) # Using copy.copy()
# Modify the top-level element
shallow_clone[0] = 99
print("After top-level change:")
print("Original:", original)
print("Clone:", shallow_clone)
# Modify the nested list (shared reference)
shallow_clone[2].append(5)
print("\nAfter nested change:")
print("Original:", original) # The nested list is changed!
print("Clone:", shallow_clone)
After top-level change:
Original: [1, 2, [3, 4]]
Clone: [99, 2, [3, 4]]
After nested change:
Original: [1, 2, [3, 4, 5]]
Clone: [99, 2, [3, 4, 5]]
The top-level integer was changed only in the clone. The nested list was changed in both because the shallow copy only copied its reference.
Shallow copy is not sufficient for objects containing other mutable objects.
Deep Copy: The deepcopy() Method
A deep copy creates a new object. It then recursively adds copies of the objects found in the original.
It creates a fully independent clone. Use the copy module's deepcopy() function.
import copy
original = [1, 2, [3, 4]]
deep_clone = copy.deepcopy(original) # Using copy.deepcopy()
# Modify the nested list
deep_clone[2].append(5)
print("Original:", original)
print("Deep Clone:", deep_clone)
Original: [1, 2, [3, 4]]
Deep Clone: [1, 2, [3, 4, 5]]
The change is completely isolated to the deep clone. The original nested list remains untouched.
Deep copy is the safest way to create a fully independent duplicate. It is essential for complex, nested data structures. Learn more about handling such structures in our guide on Python Objects in Objects: Nested Data Guide.
Copying Custom Class Objects
For your own classes, Python's copy module works by default. It uses the class's __dict__ attribute.
You can control copying behavior by defining the __copy__() and __deepcopy__() special methods.
import copy
class Player:
def __init__(self, name, inventory):
self.name = name
self.inventory = inventory # Assume this is a list
player1 = Player("Hero", ["Sword", "Shield"])
player2 = copy.deepcopy(player1)
player2.name = "Clone"
player2.inventory.append("Potion")
print("Player1 Name:", player1.name, "Inventory:", player1.inventory)
print("Player2 Name:", player2.name, "Inventory:", player2.inventory)
Player1 Name: Hero Inventory: ['Sword', 'Shield']
Player2 Name: Clone Inventory: ['Sword', 'Shield', 'Potion']
The deepcopy worked perfectly on the custom object. The inventory lists are now separate. To understand the foundation of such objects, read Python Objects: Classes, Instances, and Methods Guide.
When to Use Shallow vs Deep Copy
Choosing the right method depends on your data structure.
Use a shallow copy when your object contains only immutable data (integers, strings, tuples). Also use it when you are okay with sharing references to inner mutable objects.
Use a deep copy when your object contains other mutable objects (lists, dicts, other class instances) and you need complete independence. This is the most common and safest choice for cloning.
Common Pitfalls and Best Practices
Avoid using assignment for copying mutable data. Always be explicit about your intent to copy.
Remember that deep copying can be slower and use more memory for large, complex objects. Use it judiciously.
For data that needs to be sent over a network or saved to a file, consider serialization (like JSON) instead of cloning. Our JSON Serialization Guide for Custom Python Objects can help.
Conclusion
Cloning objects in Python is essential for writing predictable code. The assignment operator creates references, not copies.
Use copy.copy() for a shallow copy of simple structures. Use copy.deepcopy() for a complete, independent duplicate of complex, nested objects.
Understanding this distinction will help you avoid subtle bugs and manage your program's state effectively.