Python
Dictionary
Iteration
Programming
Coding Tips

How to iterate through Dictionary and change values?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Updating dictionary values while iterating is a normal Python task, and it is safe as long as the set of keys does not change. The rule to remember is simple: changing existing values is fine, but adding or removing keys while iterating over the live dictionary view can raise errors.

So the real question is not "can I modify a dictionary during iteration?" It is "am I only changing values, or am I also changing the dictionary's size?"

Change Existing Values In Place

If the keys stay the same, iterating through items() and assigning back by key is valid:

python
1def clamp_score(value: int) -> int:
2    if value < 0:
3        return 0
4    if value > 100:
5        return 100
6    return value
7
8
9scores = {"alice": 120, "bob": 87, "carol": -4}
10
11for name, score in scores.items():
12    scores[name] = clamp_score(score)
13
14print(scores)

This works because the dictionary shape is unchanged. You are only replacing existing values.

Build a New Dictionary When That Is Clearer

Sometimes mutating in place is not the best design. If you want to preserve the original mapping or make the transformation easier to reason about, use a dictionary comprehension:

python
1prices = {"A": 10.0, "B": 15.5, "C": 7.25}
2
3adjusted = {
4    code: round(value * 0.9, 2)
5    for code, value in prices.items()
6}
7
8print("original:", prices)
9print("adjusted:", adjusted)

This is often the better choice in data pipelines and functional-style transformations where preserving inputs matters.

Do Not Add or Remove Keys Mid-Iteration

The dangerous case is changing the key set while iterating directly over the dictionary:

python
1settings = {"timeout": 30, "debug": 1, "legacy": 1}
2
3for key in list(settings.keys()):
4    if key == "legacy":
5        settings.pop(key)
6
7settings["mode"] = "prod"
8print(settings)

The important detail is list(settings.keys()). That creates a stable snapshot of the keys so removal is safe during the loop.

Without the snapshot, Python can raise RuntimeError: dictionary changed size during iteration.

Rule-Based Updates

If each key needs a different transformation, a rule map is often cleaner than a long chain of if statements:

python
1rules = {
2    "age": int,
3    "name": lambda s: s.strip().title(),
4    "active": lambda v: str(v).lower() in {"1", "true", "yes"},
5}
6
7record = {"age": "42", "name": "  maria ", "active": "yes"}
8
9for key, value in record.items():
10    if key in rules:
11        record[key] = rules[key](value)
12
13print(record)

This makes the per-key behavior explicit and easier to extend.

Nested Dictionaries Need a Different Strategy

For nested data, a recursive transformation helper is often more readable than deeply nested loops:

python
1from collections.abc import Mapping
2
3
4def trim_strings(obj):
5    if isinstance(obj, Mapping):
6        return {k: trim_strings(v) for k, v in obj.items()}
7    if isinstance(obj, list):
8        return [trim_strings(x) for x in obj]
9    if isinstance(obj, str):
10        return obj.strip()
11    return obj
12
13
14raw = {
15    "service": " payments ",
16    "flags": {"region": " us-east ", "enabled": True},
17}
18
19print(trim_strings(raw))

That approach is usually better than trying to mutate nested structures ad hoc in several separate loops.

Common Pitfalls

The biggest mistake is removing or adding keys while iterating over the live dictionary view. That changes the dictionary's size and can trigger a runtime error.

Another common issue is mutating a shared dictionary in place when the caller expected the original mapping to remain unchanged. If the input should be preserved, build a new dictionary instead.

Developers also sometimes hide many unrelated transformation rules inside one giant loop. Once the rules become complex, a rule map or helper function is usually clearer.

Finally, be careful with nested dictionaries. Simple top-level loops do not scale well once values themselves contain lists or mappings.

Summary

  • Updating existing dictionary values during iteration is safe if the key set does not change.
  • Use direct assignment for simple in-place value transformations.
  • Use a new dictionary when preserving the original mapping is clearer.
  • Iterate over a snapshot such as list(d.keys()) when you must add or remove keys.
  • For nested structures, prefer centralized helper logic over scattered mutation loops.

Course illustration
Course illustration

All Rights Reserved.