Reputation: 13
Summary:
I want to iterate over a dictionary which is dynamic.
Here dynamic means we will be deleting one key,value pair after some condition. So, lenght of dictionary will be changed. But I am getting error in python:
RuntimeError: dictionary changed size during iteration
Example:
Lets have a code here:
a = {'p':'q','q':'r','s':'t'}
for key,value in a.items():
if key == 'q':
<some code here>
del a[key]
<some code here>
It gives Runtime Error over changing size of dict.
Upvotes: 1
Views: 1722
Reputation: 236
items()
method returns a generator that will return a tuple (key, value)
for every iteration step until it will raise and StopIteration
. Please see iterator protocol.
You can convert the generator to a list by doing list(a.items())
and then it will work because now you have the entire list of keys and values and is no more linked to the dictionary.
Upvotes: 0
Reputation: 21
Yes, you can't change the size of a dict while you are iterating on it.
I suggest to create a copy of dict, delete element from the copy and then make the right assignement.
Make sure to do the copy with dict.copy() otherwise the code don't work to
a = { 'a' : 1, 'b' : 2, 'c' : 3 }
b = a.copy()
for key in a:
if i=='a':
del [key]
a = b
Enjoy!
Upvotes: 1
Reputation: 8273
Do not delete key
while iterating dict
. Using dict comprehension to create a new dict and assign to your variable a
if needed
{k:v for k,v in a.items() if k!='q'}
Upvotes: 3
Reputation: 1069
You're not really using the value there so you could copy the keys instead and get the same behaviour by doing this -
a = {'p':'q','q':'r','s':'t'}
for key in list(a):
if key == 'q':
<some code here>
del a[key]
<some code here>
Upvotes: 2