Issue 6830: Some uniformness in defaultdict (original) (raw)

I found the syntax of collections.defaultdict is confusing, at least to me.

When I need a defaultdict of int, that is, a defaultdict which contains int objects, I can write simply: a = defaultdict(int)

However, when I want a defaultdict of defaultdict of something, I can't write: d = defaultdict(defaultdict(int))

This raises TypeError.

I understand the argument of defaultdict is not a type (or class), but a factory by definition. So I should to write: d = defaultdict(lambda: defaultdict(int))

But this syntax is somehow confusing to me. Am I missing some important feature of defaultdict?

The workaround that I've found is:

import collections class __Helper(object): def getitem(self, ctor): return lambda: collections.defaultdict(lambda: ctor()) genericdefaultdict = __Helper()

This helper introduce some generics flavor in defaultdict. The above cases can be spelt out:

a = genericdefaultdictint d = genericdefaultdictgenericdefaultdict[int]

This won't change -- the argument of defaultdict is simply a callable that is called with no arguments and returns the default value.

It works with int because int() can be called without arguments and yields 0; however, defaultdict cannot. Therefore, the lambda expression you wrote is one of the correct ways to spell this.