RuntimeError: dictionary changed size during iteration
You added or removed keys from a dict while looping over it. Loop over a copy of the keys, or build a new dict.
What it means
A dict iterator walks the internal table in order. Adding or removing keys can reorganise that table mid-walk, so Python refuses rather than silently skipping or repeating items. Sets raise the same error. Lists do not raise — they skip items instead, which is worse.
Common causes
1. Deleting entries while looping
Removing keys changes the size the iterator is tracking.
Breaks
for key in stock:
if stock[key] == 0:
del stock[key]Works
stock = {k: v for k, v in stock.items() if v != 0}2. Adding derived keys while looping
Adding a key during iteration is just as unsafe as removing one.
Breaks
for name in prices:
prices[name + "_tax"] = prices[name] * 1.2Works
for name in list(prices):
prices[name + "_tax"] = prices[name] * 1.23. Mutating inside a function called from the loop
The loop looks innocent; the helper it calls removes the key.
Breaks
for user_id in sessions:
expire_if_old(user_id) # does del sessions[user_id]Works
for user_id in list(sessions):
expire_if_old(user_id)How to find it in your own code
Iterate over list(d) or list(d.items()) — a snapshot — when you need to modify the dict in the loop. When you are filtering, a dict comprehension that builds a new dict is cleaner and has no ordering surprises.
Still not sure why yours breaks?
Paste it into the visualizer and watch it run line by line, with every variable at every step. Free, and it runs in your browser.