defaultdict()
takes a factory, and will call the factory each time it needs a default value. If you pass in int
, every time a new default value is needed, int()
is called.
The code you found use a lambda
as the factory. Every time you call it, it returns a new defaultdict(...)
object. Now, the defaultdict()
object still needs a factory, and in this case, it just reuses the same factory object.
This works, because the name _dict
is only looked up when call the lambda, and you can only call the lambda once it is created and assigned to the name _dict
; the dependency cycle works because the self-reference is only looked up after the reference has been created.
This is a lot like recursion, but not the same thing. Recursion automatically calls the same function until an end-condition breaks the call chain. But here, there is no automatic call chain! When you need a new default value, the lambda
is called, and that returns a new defaultdict(_dict)
object. And that's it. There is no automatic chain, the newly-minted defaultdict
has a factory of it's own configured, but it is not automatically called.
The concept is called autovivication.