Multiple levels of 'collection.defaultdict' in Python
Use:
from collections import defaultdictd = defaultdict(lambda: defaultdict(int))
This will create a new defaultdict(int)
whenever a new key is accessed in d
.
Another way to make a pickleable, nested defaultdict is to use a partial object instead of a lambda:
from functools import partial...d = defaultdict(partial(defaultdict, int))
This will work because the defaultdict class is globally accessible at the module level:
"You can't pickle a partial object unless the function [or in this case, class] it wraps is globally accessible ... under its __name__ (within its __module__)" -- Pickling wrapped partial functions
Look at nosklo's answer here for a more general solution.
class AutoVivification(dict): """Implementation of perl's autovivification feature.""" def __getitem__(self, item): try: return dict.__getitem__(self, item) except KeyError: value = self[item] = type(self)() return value
Testing:
a = AutoVivification()a[1][2][3] = 4a[1][3][3] = 5a[1][2]['test'] = 6print a
Output:
{1: {2: {'test': 6, 3: 4}, 3: {3: 5}}}