Of course! Cloning a dictionary in Python means creating a new dictionary object that contains the same key-value pairs as the original. The key is to understand the difference between a shallow copy and a deep copy, as they behave differently with nested objects.

Here’s a complete guide, from the most common methods to the important distinctions.
The Short Answer: The Most Common Methods
For most cases, you'll want one of these two:
- For a Shallow Copy: Use the dictionary's
.copy()method or thedict()constructor. - For a Deep Copy: Use the
copy.deepcopy()function from thecopymodule.
Shallow Copy
A shallow copy creates a new dictionary, but it inserts references to the original objects (for values) into the new dictionary. This means:
- If the value is an immutable type (like an integer, string, or tuple), it's perfectly safe. Changing it in the new dictionary won't affect the old one because you're just creating a new immutable object.
- If the value is a mutable type (like another list, dictionary, or set), the new dictionary will point to the exact same object in memory. Modifying this object through the new dictionary will also modify it in the original dictionary.
Method 1: The .copy() Method (Most Pythonic)
This is the most common and readable way to create a shallow copy.

original_dict = {'name': 'Alice', 'scores': [88, 92, 79]}
shallow_copy = original_dict.copy()
print(f"Original: {original_dict}")
print(f"Shallow Copy: {shallow_copy}")
# Let's modify a mutable value in the copy
shallow_copy['scores'].append(100) # Modifies the list object
print("\n--- After modifying the list in the copy ---")
print(f"Original: {original_dict}") # The original is also changed!
print(f"Shallow Copy: {shallow_copy}")
Output:
Original: {'name': 'Alice', 'scores': [88, 92, 79]}
Shallow Copy: {'name': 'Alice', 'scores': [88, 92, 79]}
--- After modifying the list in the copy ---
Original: {'name': 'Alice', 'scores': [88, 92, 79, 100]} # <-- Changed!
Shallow Copy: {'name': 'Alice', 'scores': [88, 92, 79, 100]}
Method 2: The dict() Constructor
This achieves the exact same result as .copy().
original_dict = {'name': 'Bob', 'city': 'New York'}
shallow_copy = dict(original_dict)
print(f"Original: {original_dict}")
print(f"Shallow Copy: {shallow_copy}")
# Modifying an immutable value works as expected
shallow_copy['name'] = 'Charlie'
print("\n--- After modifying a string in the copy ---")
print(f"Original: {original_dict}") # The original is NOT changed
print(f"Shallow Copy: {shallow_copy}")
Output:
Original: {'name': 'Bob', 'city': 'New York'}
Shallow Copy: {'name': 'Bob', 'city': 'New York'}
--- After modifying a string in the copy ---
Original: {'name': 'Bob', 'city': 'New York'}
Shallow Copy: {'name': 'Charlie', 'city': 'New York'}
Method 3: The Unpacking Operator () (Python 3.5+)
This is a modern and flexible way to create a new dictionary.

original_dict = {'a': 1, 'b': 2}
shallow_copy = {**original_dict}
print(f"Original: {original_dict}")
print(f"Shallow Copy: {shallow_copy}")
Deep Copy
A deep copy creates a completely independent clone of the original dictionary and all objects nested inside it. It recursively copies every object, creating new copies even for nested mutable types. Changes to the deep copy will never affect the original dictionary.
You need to import the copy module to use this.
import copy
original_dict = {
'name': 'David',
'skills': ['Python', 'SQL'],
'address': {
'street': '123 Main St',
'zip': '10001'
}
}
# Create a deep copy
deep_copy = copy.deepcopy(original_dict)
print(f"Original: {original_dict}")
print(f"Deep Copy: {deep_copy}")
# Modify a nested list in the deep copy
deep_copy['skills'].append('Java')
# Modify a nested dictionary in the deep copy
deep_copy['address']['street'] = '456 Oak Ave'
print("\n--- After modifying nested objects in the deep copy ---")
print(f"Original: {original_dict}") # The original is UNCHANGED
print(f"Deep Copy: {deep_copy}")
Output:
Original: {'name': 'David', 'skills': ['Python', 'SQL'], 'address': {'street': '123 Main St', 'zip': '10001'}}
Deep Copy: {'name': 'David', 'skills': ['Python', 'SQL'], 'address': {'street': '123 Main St', 'zip': '10001'}}
--- After modifying nested objects in the deep copy ---
Original: {'name': 'David', 'skills': ['Python', 'SQL'], 'address': {'street': '123 Main St', 'zip': '10001'}} # <-- Unchanged!
Deep Copy: {'name': 'David', 'skills': ['Python', 'SQL', 'Java'], 'address': {'street': '456 Oak Ave', 'zip': '10001'}}
The "Gotcha": Assignment ()
This is not a copy method. It simply creates a new name (variable) that points to the exact same dictionary object in memory.
original_dict = {'user': 'Eve', 'id': 123}
alias = original_dict # This is an alias, not a copy
print(f"Original: {original_dict}")
print(f"Alias: {alias}")
# Modifying the alias modifies the original
alias['id'] = 456
print("\n--- After modifying the alias ---")
print(f"Original: {original_dict}") # The original IS changed
print(f"Alias: {alias}")
Output:
Original: {'user': 'Eve', 'id': 123}
Alias: {'user': 'Eve', 'id': 123}
--- After modifying the alias ---
Original: {'user': 'Eve', 'id': 456} # <-- Changed!
Alias: {'user': 'Eve', 'id': 456}
Summary Table: Which Method to Use?
| Method | Type | When to Use | Example |
|---|---|---|---|
dict.copy() |
Shallow | Most common use case. When your dictionary contains only immutable values or you intentionally want nested mutable objects to be shared. | new_dict = old_dict.copy() |
dict() |
Shallow | Same as .copy(). A good alternative, often used for clarity when creating a dict from another iterable. |
new_dict = dict(old_dict) |
| `{old_dict}`** | Shallow | Same as .copy(). Very flexible, especially when you want to add/override keys at the same time. |
new_dict = {**old_dict, 'new_key': 'new_val'} |
copy.deepcopy() |
Deep | When you need a fully independent clone. Essential when your dictionary contains other mutable objects (lists, dicts, sets) that you want to modify without affecting the original. | import copy; new_dict = copy.deepcopy(old_dict) |
alias = old_dict |
Alias | Almost never for cloning. Only when you want two variables to refer to the exact same dictionary object. | alias = old_dict |
Final Recommendation
- If you're not sure and need a truly independent copy, always use
copy.deepcopy(). It's safer and prevents unexpected bugs. - If you are certain your dictionary only contains simple, immutable values (like strings, numbers, booleans), or if you intentionally want to share nested mutable data,
.copy()is efficient and idiomatic.
