I came across this code from https://quanttype.net/posts/2016-03-29-defaultdicts-all-the-way-down.html and I am not able to understand how or why this is working. I would love to know how someone could visualize this and understand this
Running this inside a debugger did not yield an understanding
def fix(f):
return lambda *args, **kwargs: f(fix(f), *args, **kwargs)
>>> from collections import defaultdict
>>> d = fix(defaultdict)()
>>> d["a"]["b"]["c"]
defaultdict(<function <lambda> at 0x105c4bed8>, {})
Let's consider a slightly simpler version of fix
:
def fix(f):
return lambda: f(fix(f))
When we call fix(defaultdict)
, we of course get lambda: defaultdict(fix(defaultdict))
. It will return a separate lambda
each time, but all of those lambda
functions have the same net effect. When the first lambda
is called, it creates another one, and sets that as the factory for the defaultdict
that it returns.
The defaultdict
that we get back, will use the lambda
to create default values. So when a key-value pair is inserted, the value will become another defaultdict, that has its own lambda, which can do the same thing.
This lets us store keys as deep as we want without creating the sub-dicts first, because at each level the new layer will automatically be created if needed (and that layer is set up to create the next when needed, and so on).
The fix
in the actual code just forwards additional parameters to the defaultdict
constructor. The sample code doesn't use that functionality, but it could be used to initialize the contents instead of assigning them one at a time (see the documentation for defaultdict
for more details).