collections.defaultdict is a fun utility that is used to create an indexable collection that will implicitly create an entry if a key is read that doesn’t yet exist. The value to be used will be instantiated using the type passed.
Example:
import collections
c = collections.defaultdict(str)
c['missing_key']
print(dict(c))
#{'missing_key': ''}
What if you want to create a dictionary that recursively and implicitly creates dictionary-type members as far down as you’d like to go? Well, it turns out that you can also pass a factory-function as the argument to collections.defaultdict:
import collections
def dict_maker():
return collections.defaultdict(dict_maker)
x = dict_maker()
x['a']['b']['c'] = 55
print(x)
#defaultdict(<function dict_maker at 0x10e1dbed8>, {'a': defaultdict(<function dict_maker at 0x10e1dbed8>, {'b': defaultdict(<function dict_maker at 0x10e1dbed8>, {'c': 55})})})
To make the result a little nicer:
import json
print(json.dumps(x))
#{"a": {"b": {"c": 55}}}