14

This question is not a duplicate of Dictionary changed size during iteration - Code works in Py2 Not in Py3. This question asks why this is not enforced for list, not how to fix the code.

Python will happily execute

li = [1, 2, 3]
for n in li:
    if n % 2 == 0:
        li.remove(n)

But if we try with a dict:

a = {1: '', 2: '', 3: ''}   
for n in a:                 
    if n % 2 == 0:          
        a.pop(n)

We get

RuntimeError: dictionary changed size during iteration

Since I assume this is an implementation detail, I'll note that this was tested with CPython 3.7.0 and 3.4.2.

DeepSpace
  • 78,697
  • 11
  • 109
  • 154
  • 6
    That's not a suitable duplicate. This is a "why?" question, not a "how do I make it work in python 3" question. The answers there don't explain why this exception is thrown. – Aran-Fey Mar 06 '19 at 20:09
  • 3
    In the linked answer it did provide the why though. `iter(a)` is providing a `dict_keyiterator` view and the view itself doesn't function like a `list`. Unless the question is, why doesn't `view` objects allow for changes during iteration... which I can surmise is due to it being a view-copy of the orig object. – r.ook Mar 06 '19 at 20:11
  • 4
    [PEP 3106](https://www.python.org/dev/peps/pep-3106/) discusses the motivation –  Mar 06 '19 at 20:15
  • If I had to guess, it's because a `dict` is a more complicated structure that is much harder to iterate when it changes. – Mark Ransom Mar 06 '19 at 20:20
  • 4
    The check has been there since the [original iterator commit](https://github.com/python/cpython/commit/59d1d2b434e8cf79e8b1321f148254c68f56c1f7), with no explanation in the commit message. If I had to guess, I'd say they put the check in for dicts because they *could*, whereas they couldn't with lists because of backward compatibility with the old `__getitem__` iteration. – user2357112 Mar 06 '19 at 20:25
  • I believe the dupe is right this time. I actually had an answeretyped up but if OP is not happy with the dupe I can post it. The [relevant documentation](https://docs.python.org/3/library/stdtypes.html#dict-views) shows that these dict-views are "Set-like" and behaves much like a `set` when changed during iteration. – r.ook Mar 06 '19 at 20:41

0 Answers0