shodowsjedi shodowsjedi - 3 months ago 6
Python Question

Python Dictionary DataStructure which method d[] or d.get()?

While Using Python Dictionary DataStructure (which contains key-value pair) if i want to retrieve some value from my Dictionary i have two options d[''] and g.get('key') so i am confused now which is better and Why ?? I understand both some way but when it comes to memory consumption and evaluation in memory which one is better ??

Hoping for some Positive reply,

Regards.

Answer

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

  1. A KeyError raised
  2. A callback invoked
  3. 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. :-)

Comments