[Python-Dev] Proposal: defaultdict

Guido van Rossum guido at python.org
Sat Feb 18 05:14:28 CET 2006

On 2/17/06, Nick Coghlan <ncoghlan at gmail.com> wrote:
> And this is where the question of whether has_key/__having__ return True or
> False when default_factory is set is important. If they return False, then the
> LBYL (if key in d:) and EAFTP (try/except) approaches give *different answers*.
> More importantly, LBYL will never have side effects, whereas EAFTP may.
> If the methods always return True (as Martin suggests), then we retain the
> current behaviour where there is no real difference between the two
> approaches. Given the amount of time spent in recent years explaining this
> fact, I don't think it is an equivalence that should be broken lightly (IOW,
> I've persuaded myself that I agree with Martin)
> The alternative would be to have an additional query API "will_default" that
> reflects whether or not a given key is actually present in the dictionary ("if
> key not in d.keys()" would serve a similar purpose, but requires building the
> list of keys).

Looking at it from the "which invariants hold" POV isn't always the
right perspective.

Reality is that some amount of code that takes a dict won't work if
you give it a dict with a default_factory. Well, that's nothing new.
Some code also breaks if you pass it a dict containing key or value
types it doesn't expect, or if you pass it an anydbm instance, or
os.environ on Windows (which implements case-insensitive keys).

>From the POV of someone who decides to use a dict with a
default_factory (or overriding on-missing()), having the 'in' operator
always return True is d*mn annoying -- it means that any kind of
introspection of the dict doesn't work. Take for example the multiset
use case. Suppose you're aware that you're using a dict with this
special behavior. Now you've built up your multiset and now you want
to use it. Part of your app is interested in knowing the list of
values associated with each key. But another part may be interested
only in whether a particular key hs *any* values associated. If "key
in d" returns whether that key is currently present, you can write

  if key in d:
      print "whatever"

But under Martin and your proposed semantics, you'd have to write

  if d.get(key):
      print "whatever"

or (worse)

  if d[key]: # inserts an empty list into the dict!
      print "whatever"

I'd much rather be able to write "if key in d" and get the result I want...

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

More information about the Python-Dev mailing list