dict provides .setdefault(), which will allow you to assign values, of any type, to missing keys on the fly:
>>> d = dict()
>>> d.setdefault('missing_key', [])
[]
>>> d
{'missing_key': []}
Whereas, if you use defaultdict to accomplish the same task, then the default value is generated on demand whenever you try to access or modify a missing key:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d['missing_key']
[]
>>> d
defaultdict(<class 'list'>, {'missing_key': []})
However, the following piece of code implemented with defaultdict raises a KeyError instead of creating the item with default value, {}:
trie = collections.defaultdict(dict)
for word in words:
t = trie
for c in word:
t = t[c]
t["*"] = word
Using .setdefault() works ok:
trie = {}
for word in words:
t = trie
for c in word:
t = t.setdefault(c, {})
t["*"] = word
checking before access, works ok too:
trie = {}
for word in words:
t = trie
for c in word:
if c not in t:
t[c] = {}
t = t[c]
t["*"] = word
What am I missing when using collections.defaultdict()?
NB I am trying to build a Trie structure out of a list of words. For example:
words = ["oath", "pea", "eat", "rain"]
trie = {'o': {'a': {'t': {'h': {'*': 'oath'}}}}, 'p': {'e': {'a': {'*': 'pea'}}}, 'e': {'a': {'t': {'*': 'eat'}}}, 'r': {'a': {'i': {'n': {'*': 'rain'}}}}}