How to delete items from a dictionary while iterating over it?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Python, you should not delete keys from a dictionary while iterating over that same live dictionary view. Doing so changes the dictionary size during iteration and usually raises a RuntimeError.
Why the Direct Approach Fails
This looks tempting:
But it fails because the iterator expects the dictionary structure to remain stable while it is walking the keys. Deleting entries changes the size, invalidating that assumption.
Safe Pattern 1: Iterate Over a Snapshot
If you need to mutate the original dictionary object, iterate over a separate list of keys.
This works because list(data.keys()) creates a snapshot that does not change as the dictionary changes.
Safe Pattern 2: Build a New Dictionary
Often the cleanest solution is not in-place deletion at all, but filtering into a new dictionary.
If replacing the original variable is acceptable:
This is usually the most readable approach when object identity does not matter.
Safe Pattern 3: Two-Pass Deletion
For more complex logic, a two-pass approach is often clearer.
This separates the decision step from the mutation step, which is easier to debug when the condition is more than a one-line filter.
Which Pattern Should You Prefer
A simple rule works well:
- need to keep the same dictionary object: iterate over a snapshot or use two passes
- fine with a replacement dictionary: use a comprehension
That distinction matters when other parts of the program hold references to the original object.
Nested Dictionaries Need the Same Care
The same problem appears when traversing nested dictionaries recursively. If you modify a nested dictionary while iterating over its live entries, you can trigger the same kind of runtime error.
In deep transformations, building new dictionaries recursively is often safer than mutating in place.
Why Comprehensions Are Often Best
For filtering tasks, comprehensions are usually both safer and clearer because they express the "keep" rule directly:
That is often easier to understand than collecting keys to delete and mutating afterward.
Common Pitfalls
Deleting from the same dictionary you are directly iterating over is the core mistake.
Choosing in-place mutation when a filtered replacement dictionary would be simpler often makes the code harder to read.
Forgetting that shared references may require preserving the same dictionary object can make a comprehension-based replacement incorrect in a larger program.
Mixing selection logic and deletion logic inside one loop makes debugging more difficult than a two-pass design.
Summary
- Do not delete keys directly from a dictionary while iterating over its live view.
- If you need in-place mutation, iterate over a snapshot such as
list(data.keys()). - If replacement is acceptable, a dictionary comprehension is usually the cleanest solution.
- A two-pass approach works well when the deletion condition is more complex.
- Choose the pattern based on whether object identity or code clarity matters more in your situation.

