All you need is to subclass OrderedDict
and add a __missing__
function:
from collections import OrderedDict
class DefaultOrderedDict(OrderedDict):
def __missing__(self, key):
self[key] = type(self)()
return self[key]
The default dict
type will call a __missing__
method if present before raising a KeyError
, which is what the defaultdict
type makes use of.
See the dict
documentation (scroll down to the d[key]
description):
New in version 2.5: If a subclass of dict defines a method
__missing__()
, if the key key is not present, thed[key]
operation calls that method with the key key as argument. Thed[key]
operation then returns or raises whatever is returned or raised by the__missing__(key)
call if the key is not present. No other operations or methods invoke__missing__()
. If__missing__()
is not defined,KeyError
is raised.__missing__()
must be a method; it cannot be an instance variable.
Demo:
>>> d = DefaultOrderedDict()
>>> d['a']['b']['c'] = 'd'
>>> d['a'][1][2] = 3
>>> d['f']['g']['e'] = 'g'
>>> d['f'][5][6] = 7
>>> d['a']['foo']['bar'] = 'hello world'
>>> [(i, j, k, d[i][j][k]) for i in d for j in d[i] for k in d[i][j]]
[('a', 'b', 'c', 'd'), ('a', 1, 2, 3), ('a', 'foo', 'bar', 'hello world'), ('f', 'g', 'e', 'g'), ('f', 5, 6, 7)]