How to Avoid "Runtimeerror: Dictionary Changed Size During Iteration" Error

How to avoid RuntimeError: dictionary changed size during iteration error?

In Python 3.x and 2.x you can use use list to force a copy of the keys to be made:

for i in list(d):

In Python 2.x calling keys made a copy of the keys that you could iterate over while modifying the dict:

for i in d.keys():

But note that in Python 3.x this second method doesn't help with your error because keys returns an a view object instead of copying the keys into a list.

How to solve dictionary changed size during iteration error?

Alternative solutions

If you're looking for the smallest value in the dictionary you can do this:

min(dictionary.values())

If you cannot use min, you can use sorted:

sorted(dictionary.values())[0]

Why do I get this error?

On a side note, the reason you're experiencing an Runtime Error is that in the inner loop you modify the iterator your outer loop is based upon. When you pop an entry that is yet to be reached by the outer loop and the outer iterator reaches it, it tries to access a removed element, thus causing the error.

If you try to execute your code on Python 2.7 (instead of 3.x) you'll get, in fact, a Key Error.

What can I do to avoid the error?

If you want to modify an iterable inside a loop based on its iterator you should use a deep copy of it.

python RuntimeError: dictionary changed size during iteration

Like the message says: you changed the number of entries in obj inside of expandField() while in the middle of looping over this entries in expand.

You might try instead creating a new dictionary of the form you wish, or somehow recording the changes you want to make, and then making them AFTER the loop is done.

RuntimeError: dictionary changed size during iteration but it's not changed in the loop

The main Problem is when dfs method is called it uses this line

for neighbor in adjacent[c]: 

This just returns the associated value if it exists in defaultdict, if it doesn't exist in it, it creates and adds a key if you try to access key that doesn't exist.

Potential line that triggers accessing adjacent defaultdict without knowing whether it exist or not is

if dfs(neighbor):

neighbor might be or might not be in adjacent defaultdict this causes defaultdict to change. You might check if it exists if not u might want to skip.

RuntimeError: dictionary changed size during iteration - how to solve?

How big is your dict? If it is not huge, then you could do:

new_dict = {}
for k, v in ref_dict.items():
if isinstance(k, str):
new_dict[k.upper()] = v
else:
new_dict[k] = v

ref_dict = new_dict

In the other case, you may need to review your creation of ref_dict and modify the key there.

Also, one could modify your original code as follows change ref_dict. But it's worth mentioning that it would add new elements to ref_dict. For example

ref_dict = {'abc' : 1}

### change of code
keys = [k for key in ref_dict]

for k in keys:
if isinstance(k, str):
ref_dict[k.upper()] = ref_dict[k]
# else part is not neccessary
# else:
# ref_dict[k] = v

# now ref_dict = {'abc':1, 'ABC':1}


Related Topics



Leave a reply



Submit