Why updating shallow copy dictionary doesn't update original dictionary?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
A shallow copy of a dictionary creates a new dictionary object with references to the same values. Adding, removing, or reassigning keys in the copy does not affect the original — these operations modify the copy's structure, not the shared values. However, mutating a mutable value (like a nested list or dict) through the copy does affect the original because both dictionaries reference the same object. This is the core distinction: reassignment creates a new reference, mutation modifies the shared object.
Shallow Copy Behavior
When you do copy["a"] = 100, you are replacing the copy's reference for key "a" with a new object (100). The original still references the old object (1).
Where Shallow Copy Shares State
Visualizing the References
Deep Copy for Full Independence
Ways to Create Copies
Assignment vs Copy
alias = original does not copy anything — both names point to the same dictionary object. Any change through either name affects the same object.
Common Pitfalls
- Expecting shallow copy to create fully independent nested structures: A shallow copy only copies the top-level key-value pairs. Nested mutable objects (lists, dicts, sets) are shared between the original and copy. Use
copy.deepcopy()when you need full independence of nested structures. - Confusing reassignment with mutation:
copy["key"] = new_value(reassignment) does not affect the original.copy["key"].append(item)(mutation) does affect the original because both share the same list. The distinction is whether you are changing which object a key points to (safe) or modifying the object itself (shared). - Using
=thinking it creates a copy:new_dict = old_dictcreates an alias, not a copy. Both variables reference the exact same dictionary. Any modification through either variable is visible from both. Use.copy()ordict()to create an actual independent copy. - Deep copying objects with circular references:
copy.deepcopy()handles circular references correctly by tracking already-copied objects. However, it can be slow for large, deeply nested structures. If performance matters and you know the structure, consider manually constructing the copy. - Assuming
{**original}is a deep copy: Dictionary unpacking ({**original}) creates a shallow copy, just like.copy(). Nested mutable values are still shared. This is a common misconception because the syntax looks like it is "rebuilding" the dictionary.
Summary
- Shallow copy (
.copy(),dict(),{**d}) creates a new dict but shares nested mutable objects - Adding, removing, or reassigning keys in the copy does not affect the original
- Mutating shared mutable values (lists, dicts) through the copy does affect the original
- Use
copy.deepcopy()for fully independent copies of nested structures =creates an alias (same object), not a copy — always use.copy()for an independent dictionary
Related reading
- Why use Dijkstra's Algorithm if Breadth First Search BFS can do the same thing faster?
- Why use two different algorithm for sorting arrays?
- Why we have both jagged array and multidimensional array?
- Why we use Hash Code in HashTable instead of an Index?
- Why use Abstract Base Classes in Python?
- Why use argparse rather than optparse?
- Why would I ever use tf.concat instead of tf.stack?
- Why would you run a messaging queue (eg RabbitMQ) cluster?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.