Hacker News new | ask | show | jobs
by abcxjeb284 1873 days ago
Great for expressivity of multi-level dicts (excuse the goofy example):

    state2name2visited = defaultdict(lambda: defaultdict(list))
     state2name2visited[“PA”][“Joe].append(“Pittsburgh”)
6 comments

You can expand this a bit to make it n-level depth (until you blow the stack).

  def tree():
    return defaultdict(tree)

  >>> t = tree()
  >>> t['a']['b']['c'] = 10
  >>> t
  defaultdict(<function tree at 0x10c40df28>, {'a': 
  defaultdict(<function tree at 0x10c40df28>, {'b': 
  defaultdict(<function tree at 0x10c40df28>, {'c': 10})})})
Reminds me of perl's autovivification, where you can even mix and match dicts, arrays, and scalars:

    $M{hello}[4]{world}[0]++
gives you:

    {
        'hello' => [
            undef,
            undef,
            undef,
            undef,
            {
                'world' => [
                    1
                ]
            }
        ]
    }
This is really cool, I used it to implement a (very) basic trie:

    trie_struct: Callable = lambda: defaultdict(trie_struct)

    trie = trie_struct()

    for word in words:
        ref = trie
        for char in word:
            ref = ref[char]
It won't work with words that substring other words, but its interesting.
Nice! Very expressive way to do n-levels!
Python has too many ways to do it:

    >>> state2name2visited = {}
    >>> state2name2visited.setdefault("PA", {}).setdefault("Joe", []).append("Pittsburgh")
    >>> state2name2visited
    {'PA': {'Joe': ['Pittsburgh']}}
It’s really 2 ways to do it, and the defaultdict way (I believe) would have less allocations in a deeply nested loop (since this version has to create a {} and a [] every time).

Also setdefault causes confusion for less experienced users in a way that the defaultdict format does not.

I came across this once in Peter Norvig's Udacity CS 212 course - I think it was in the discussion forums for one of the lessons. My head promptly exploded.
And here I was thinking you could only pass a type.
oo nice. i haven't seen this before and was doing something similar in a much uglier fashion.
python-box does a pretty good job on this I find.