Problem with OrderedDict

INADA Naoki songofacandy at gmail.com
Wed May 30 11:21:54 EDT 2018


>
> So working backwards, I have solved the first problem. I am no nearer to
> figuring out why it fails intermittently in my live program. The message
> from INADA Naoki suggests that it could be inherent in CPython, but I am
not
> ready to accept that as an answer yet. I will keep plugging away and
report
> back with any findings.
>

C implementation of OrderedDict checks
​all ​
"key change"
​(remove or insert key) ​
while iteration always.
But you can bypass the check by using dict methods
​.

Both of dict and OrdredDict checks size is not changed from start of
iteration.
So dict can't detect "remove + insert".

>>> od = collections.OrderedDict.fromkeys("abc")
>>> for k in od:
...     if k == "b":
...         del od["a"]
...         od["a"] = "new"
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: OrderedDict mutated during iteration
>>> d = dict.fromkeys("abc")
>>> for k in d:
...     if k == "b":
...         del d["a"]
...         d["a"] = "new"
...
>>> d
{'b': None, 'c': None, 'a': 'new'}


BTW, ​y
our original mail said "RuntimeError: dictionary changed size during
iteration".
Since it says "dictionary", the error was raised from dict, not
OrderedDict.​
You won't see "OrderedDict changed size" in normal code, because
OrderedDict checks all mutations.

>>> od = collections.OrderedDict.fromkeys("abc")
>>> for k in od:
...     if k == "b":
...         dict.__setitem__(od, "d", None)  # bypass OrderedDict checks
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: OrderedDict changed size during iteration



Currently, dict doesn't detect remove + insert.  But the Python language
doesn't permit it.

Learning these implementation detail should be just for a hobby, or for
developing Python interpreter.
When programming in Python, you should avoid these implementation details.

Regards,



More information about the Python-list mailing list