python – defaultdict of defaultdict?

python – defaultdict of defaultdict?

Yes like this:

defaultdict(lambda: defaultdict(int))

The argument of a defaultdict (in this case is lambda: defaultdict(int)) will be called when you try to access a key that doesnt exist. The return value of it will be set as the new value of this key, which means in our case the value of d[Key_doesnt_exist] will be defaultdict(int).

If you try to access a key from this last defaultdict i.e. d[Key_doesnt_exist][Key_doesnt_exist] it will return 0, which is the return value of the argument of the last defaultdict i.e. int().

The parameter to the defaultdict constructor is the function which will be called for building new elements. So lets use a lambda !

>>> from collections import defaultdict
>>> d = defaultdict(lambda : defaultdict(int))
>>> print d[0]
defaultdict(<type int>, {})
>>> print d[0][x]
0

Since Python 2.7, theres an even better solution using Counter:

>>> from collections import Counter
>>> c = Counter()
>>> c[goodbye]+=1
>>> c[and thank you]=42
>>> c[for the fish]-=5
>>> c
Counter({and thank you: 42, goodbye: 1, for the fish: -5})

Some bonus features

>>> c.most_common()[:2]
[(and thank you, 42), (goodbye, 1)]

For more information see PyMOTW – Collections – Container data types and Python Documentation – collections

python – defaultdict of defaultdict?

I find it slightly more elegant to use partial:

import functools
dd_int = functools.partial(defaultdict, int)
defaultdict(dd_int)

Of course, this is the same as a lambda.

Leave a Reply

Your email address will not be published. Required fields are marked *