"dictionary changed size during iteration" error in Python 3 but not in Python 2

Peter Otten __peter__ at web.de
Sun Aug 23 11:40:13 EDT 2020


Chris Green wrote:

>> >1 - Why doesn't it error in Python 2?
>> 
>> The dict internal implementation has changed. I don't know the
>> specifics, but it is now faster and maybe smaller and also now preserves
>> insert order.
>> 
> Ah, that probably explains it then.

But if you try to modify a dict while you iterate over it in py2 you trigger 
the same error:

$ python
Python 2.7.6 (default, Nov 13 2018, 12:45:42) 
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> d = dict(a=1)
>>> for k in d: del d["a"]
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

If you look at the 2.7 mailbox code you'll find that the iteritems() method 
delegates to iterkeys() which in turn uses keys(), not iterkeys() as one 
might expect,

        for key in self._toc.keys():
            yield key

of the underlying _toc dict, and in py2 keys() creates a list of keys.

In py3 the above loop becomes

        yield from self._toc.keys()

but in py3 the keys() method returns a view on the underlying dict.



More information about the Python-list mailing list