Gulati Singh
Gulati Singh

Reputation: 13

Iterate over a dynamic dictionary

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

Answers (4)

Alexandru Martin
Alexandru Martin

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

user2854287
user2854287

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

mad_
mad_

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

RnD
RnD

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

Related Questions