Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)?

like image 363
Ouroborus Avatar asked Mar 16 '23 14:03

Ouroborus


1 Answers

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.

like image 60
Martijn Pieters Avatar answered Apr 06 '23 11:04

Martijn Pieters