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.