From the Python Library Docs
d[key]
Return the item of d with key key. Raises a KeyError
if key is not in the map.
If a subclass of dict defines a method __missing__()
, if the key key is not present, the d[key]
operation calls that method with the key key as argument. The d[key]
operation then returns or raises whatever is returned or raised by the __missing__(key)
call if the key is not present. No other operations or methods invoke __missing__()
. If __missing__()
is not defined, KeyError
is raised. __missing__()
must be a method; it cannot be an instance variable. [...]
and
get(key[, default])
Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None
, so that this method never raises a KeyError
.
The difference lies in the return value. When you ask for the value corresponding to a non-existing key, you either want
- A
KeyError
raised
- A callback invoked
- A default value returned
Python provides the different functionalities through multiple methods.
There will be a performance hit using []
when the key is not found, either in calling _missing_
or raising the exception. As to which one is faster when the key IS present, I checked the source code. (I used 2.7.2 for this check.) In dictobject.c
we see:
get
calls dict_get
[]
calls dict_subscript
Now if the values are present, in dict_get
we have
if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj))
return NULL;
if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
hash = PyObject_Hash(key);
if (hash == -1)
return NULL;
}
ep = (mp->ma_lookup)(mp, key, hash);
and in dict_subscript
we have
assert(mp->ma_table != NULL);
if (!PyString_CheckExact(key) ||
(hash = ((PyStringObject *) key)->ob_shash) == -1) {
hash = PyObject_Hash(key);
if (hash == -1)
return NULL;
ep = (mp->ma_lookup)(mp, key, hash);
The only difference is that get
does an extra unpack tuple!
Significant? I have no idea. :-)