DEV Community

Samuel Ochaba
Samuel Ochaba

Posted on

Python Dictionary Views Are Live (And It Might Break Your Code)

Quick quiz. What does this print?

d = {"a": 1, "b": 2}
keys = d.keys()
print(keys)

d["c"] = 3
print(keys)
Enter fullscreen mode Exit fullscreen mode

If you said:

dict_keys(['a', 'b'])
dict_keys(['a', 'b'])
Enter fullscreen mode Exit fullscreen mode

You're wrong.

It prints:

dict_keys(['a', 'b'])
dict_keys(['a', 'b', 'c'])  # ← Updated automatically!
Enter fullscreen mode Exit fullscreen mode

Dictionary Views Are Live

.keys(), .values(), and .items() don't return copies.

They return view objects—live windows into the dictionary that update automatically when the dictionary changes.

>>> person = {"name": "Alice", "age": 30}
>>> k = person.keys()
>>> k
dict_keys(['name', 'age'])

>>> person["city"] = "NYC"  # Add a key
>>> k                       # View updated automatically
dict_keys(['name', 'age', 'city'])
Enter fullscreen mode Exit fullscreen mode

This is by design. Views are memory-efficient—they don't copy data.

But it can cause bugs if you're not expecting it.


The Bug This Causes

Imagine you're iterating over dictionary keys while modifying the dictionary:

config = {"debug": True, "verbose": False, "temp_flag": True}

# Remove all flags that are True
for key in config.keys():
    if config[key] is True:
        del config[key]  # 💥 RuntimeError!
Enter fullscreen mode Exit fullscreen mode

You get:

RuntimeError: dictionary changed size during iteration
Enter fullscreen mode Exit fullscreen mode

The view is live. When you delete a key, the view changes mid-iteration. Python catches this and throws an error.


The Fix

If you need to modify while iterating, convert to a list first:

config = {"debug": True, "verbose": False, "temp_flag": True}

# Convert to list - creates a snapshot
for key in list(config.keys()):
    if config[key] is True:
        del config[key]

print(config)  # {'verbose': False}
Enter fullscreen mode Exit fullscreen mode

list(config.keys()) creates a static copy at that moment. Now you can modify the original dictionary freely.


When Live Views Are Useful

Live views aren't just a gotcha—they're actually powerful:

# Monitor changes in real-time
cache = {}
cache_keys = cache.keys()

# ... elsewhere in your code ...
cache["user_123"] = data
cache["user_456"] = more_data

# cache_keys automatically reflects all additions
print(f"Cached: {len(cache_keys)} items")  # Always current
Enter fullscreen mode Exit fullscreen mode

No need to re-fetch .keys() every time. The view stays synchronized.

Did you know dictionary views were live? Has this ever caught you off guard?


This is adapted from my upcoming book, Zero to AI Engineer: Python Foundations.

I share excerpts like this on Substack → https://substack.com/@samuelochaba

Top comments (0)