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