[Python-ideas] Allow non-callable default_factory for defaultdict

Brandon Mintern bmintern at gmail.com
Mon Jun 2 17:05:42 CEST 2008


I have just begun using defaultdict and have found it to be very
useful for cleaning up (1) d.setdefault(key, initial_collection) and
(2) repeated d.get(key, constant) calls which all use the same
constant.

(1) is trivial because in most cases, initial_collection is something
like "set()" or "[]", and instead I can use "d = defaultdict(set)" or
"d = defaultdict(list)" to accomplish the same thing. Now, all those
d.setdefault(key...) calls become d[key]. This is much nicer, and I'm
sure most of you are familiar with it.

(2) is slightly less common, but it still comes up. This can also be
handled by defaultdict, using "d = defaultdict(lambda: constant)".
Now, all those d.get(key...) calls become d[key]. As with (1), this
makes the code significantly nicer, and perhaps some of you have used
it.

I would like to propose simplifying (2). Instead of using "d =
defaultdict(lambda: constant)", it would be nice to be able to use "d
= defaultdict(constant)". In 2.5.2:

>>> d = defaultdict("missing")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: first argument must be callable

Obviously, defaultdict is already checking its argument (perhaps it's
an assert, but still...), so it knows whether the argument is callable
or not. My proposal is that if default_factory is callable or None,
the behavior of __missing__ remains the same. Otherwise, the behavior
of __missing__ is simply to insert default_factory in the dictionary
for the key and return it.

I can see one drawback to this: there is a risk of people using
defaultdict([]) instead of defaultdict(list) with the idea that they
will do the same thing. I think this problem can be easily overcome in
the defaultdict documentation by specifically mentioning such a case
as a gotcha while also using an example with a non-callable that shows
how it is similar to using dict.get(...).

Would anyone else find such a change to be helpful?

Brandon



More information about the Python-ideas mailing list