Why del defaultdict()[k] should raise an error
Raymond Hettinger recently asked on twitter what people thought
del defaultdict()[k]
did for a k
that didn’t exist in the dict
.
There are two ways of thinking about this, one is, “it’s a defaultdict, there’s
always a value at a key, so it can never raise a KeyError”, the other is, “that
only applies to reading a value, this should still raise an error”. I
initially spent several minutes considering which made more sense, but I
eventually came around to the second view, I’m going to explain why.
The Zen of Python says, “Errors should never pass silently.” Any Java
programmer who’s seen NullPointerException
knows the result of passing
around invalid data, rather than propagating an error. There are two cases for
trying to delete a key which doesn’t exist in a defaultdict
. One is: “this
algorithm happens to sometimes produce keys that aren’t there, not an issue,
ignore it”, the other is “my algorithm has a bug, it should always produce
valid keys”. If you don’t raise a KeyError
the first case has a single
line of nice code, if you do raise an error they have a boring try
/
except KeyError
thing going on, but no big loss. However, if an error
isn’t raised and your algorithm should never produce nonexistent keys,
you’ll be silently missing a large bug in your algorithm, which you’ll have to
hope to catch later.
The inconvenience of ignoring the KeyError
to the programmer with the
algorithm that produces nonexistent keys is out weighed by the potential for
hiding a nasty bug in the algorithm of the programmer who’s code should never
produce these. Ignoring an exception is easy, trying to find the bug in your
algorithm can be a pain in the ass.