> > 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, -- https://mail.python.org/mailman/listinfo/python-list