[Python-Dev] Proposal: defaultdict

Guido van Rossum guido at python.org
Thu Feb 16 22:11:49 CET 2006

A bunch of Googlers were discussing the best way of doing the
following (a common idiom when maintaining a dict of lists of values
relating to a key, sometimes called a multimap):

  if key not in d: d[key] = []

An alternative way to spell this uses setdefault(), but it's not very readable:

  d.setdefault(key, []).append(value)

and it also suffers from creating an unnecessary list instance.
(Timings were inconclusive; the approaches are within 5-10% of each
other in speed.)

My conclusion is that setdefault() is a failure -- it was a
well-intentioned construct, but doesn't actually create more readable

Google has an internal data type called a DefaultDict which gets
passed a default value upon construction. Its __getitem__ method,
instead of raising KeyError, inserts a shallow copy (!) of the given
default value into the dict when the value is not found. So the above
code, after

  d = DefaultDict([])

can be written as simply


Note that of all the possible semantics for __getitem__ that could
have produced similar results (e.g. not inserting the default in the
underlying dict, or not copying the default value), the chosen
semantics are the only ones that makes this example work.

Over lunch with Alex Martelli, he proposed that a subclass of dict
with this behavior (but implemented in C) would be a good addition to
the language. It looks like it wouldn't be hard to implement. It could
be a builtin named defaultdict. The first, required, argument to the
constructor should be the default value. Remaining arguments (even
keyword args) are passed unchanged to the dict constructor.

Some more design subtleties:

- "key in d" still returns False if the key isn't there
- "d.get(key)" still returns None if the key isn't there
- "d.default" should be a read-only attribute giving the default value


--Guido van Rossum (home page: http://www.python.org/~guido/)

More information about the Python-Dev mailing list