Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying a Python dict while iterating over it

Let's say we have a Python dictionary d, and we're iterating over it like so:

for k,v in d.iteritems():     del d[f(k)] # remove some item     d[g(k)] = v # add a new item 

(f and g are just some black-box transformations.)

In other words, we try to add/remove items to d while iterating over it using iteritems.

Is this well defined? Could you provide some references to support your answer?

(It's pretty obvious how to fix this if it's broken, so this isn't the angle I am after.)

like image 940
NPE Avatar asked Jul 21 '11 14:07

NPE


People also ask

Can you modify dict in Python?

Modifying a value in a dictionary is pretty similar to modifying an element in a list. You give the name of the dictionary and then the key in square brackets, and set that equal to the new value.

Can you splice a dictionary in Python?

With Python, we can easily slice a dictionary to get just the key/value pairs we want. To slice a dictionary, you can use dictionary comprehension. In Python, dictionaries are a collection of key/value pairs separated by commas.


2 Answers

Alex Martelli weighs in on this here.

It may not be safe to change the container (e.g. dict) while looping over the container. So del d[f(k)] may not be safe. As you know, the workaround is to use d.items() (to loop over an independent copy of the container) instead of d.iteritems() (which uses the same underlying container).

It is okay to modify the value at an existing index of the dict, but inserting values at new indices (e.g. d[g(k)]=v) may not work.

like image 171
unutbu Avatar answered Sep 21 '22 21:09

unutbu


It is explicitly mentioned on the Python doc page (for Python 2.7) that

Using iteritems() while adding or deleting entries in the dictionary may raise a RuntimeError or fail to iterate over all entries.

Similarly for Python 3.

The same holds for iter(d), d.iterkeys() and d.itervalues(), and I'll go as far as saying that it does for for k, v in d.items(): (I can't remember exactly what for does, but I would not be surprised if the implementation called iter(d)).

like image 37
Raphaël Saint-Pierre Avatar answered Sep 18 '22 21:09

Raphaël Saint-Pierre