pythonpython-2.7dictionaryconcurrentmodificationdictview

Do Python 2.7 views, for/in, and modification work well together?


The Python docs give warnings about trying to modify a dict while iterating over it. Does this apply to views?

I understand that views are "live" in the sense that if you change the underlying dict, the view automatically reflects the change. I'm also aware that a dict's natural ordering can change if elements are added or removed. How does this work in conjunction with for/in? Can you safely modify the dict without messing up the loop?

d = dict()
# assume populated dict
for k in d.viewkeys():
    # possibly add or del element of d

Does the for/in loop iterate over all the new elements as well? Does it miss elements (because of order change)?


Solution

  • Yes, this applies to dictionary views over either keys or items, as they provide a live view of the dictionary contents. You cannot add or remove keys to the dictionary while iterating over a dictionary view, because, as you say, this alters the dictionary order.

    Demo to show that this is indeed the case:

    >>> d = {'foo': 'bar'}
    >>> for key in d.viewkeys():
    ...     d['spam'] = 'eggs'
    ... 
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    RuntimeError: dictionary changed size during iteration
    >>> d = {'foo': 'bar', 'spam': 'eggs'}
    >>> for key in d.viewkeys():
    ...    del d['spam']
    ... 
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    RuntimeError: dictionary changed size during iteration
    

    You can alter values, even when iterating over a values view, as the size of the dictionary won't then change, and the keys remain in the same order.