Coder Perfect

Why use dict.get(key) rather than dict[key]?


Today, I discovered the dict method get, which retrieves the related value for a key in a dictionary.

What is the purpose of this function? I can do dict[key] to find a value associated with a key in a dictionary, and it returns the same thing:

dictionary = {"Name": "Harry", "Age": 17}

Asked by stensootla

Solution #1

If the key is missing, you can specify a default value:

dictionary.get("bogus", default_value)

returns default value (whatever value you specify), whereas


would cause a KeyError to occur.

If omitted, default_value is None, such that

dictionary.get("bogus")  # <-- No default specified -- defaults to None

returns There aren’t any who like it.

dictionary.get("bogus", None)


Answered by unutbu

Solution #2

As previously stated, the get method has an additional parameter that identifies the value that is missing. According to the documentation

Consider the following scenario:

>>> d = {1:2,2:3}
>>> d[1]
>>> d.get(1)
>>> d.get(3)
>>> repr(d.get(3))
>>> d.get(3,1)

As mentioned here,

Previously, get was significantly slower, but now it is nearly comparable, with the added benefit of returning the default value. However, we can test on a reasonably wide list to answer all of our questions (Note that the test includes looking up all the valid keys only)

def getway(d):
    for i in range(100):
        s = d.get(i)

def lookup(d):
    for i in range(100):
        s = d[i]

Now, using timeit, time these two routines.

>>> import timeit
>>> print(timeit.timeit("getway({i:i for i in range(100)})","from __main__ import getway"))
>>> print(timeit.timeit("lookup({i:i for i in range(100)})","from __main__ import lookup"))

Because there is no function lookup, the lookup is faster than the get. This is demonstrated by the fact that

>>> def lookup(d,val):
...     return d[val]
>>> def getway(d,val):
...     return d.get(val)
>>> dis.dis(getway)
  2           0 LOAD_FAST                0 (d)
              3 LOAD_ATTR                0 (get)
              6 LOAD_FAST                1 (val)
              9 CALL_FUNCTION            1
             12 RETURN_VALUE        
>>> dis.dis(lookup)
  2           0 LOAD_FAST                0 (d)
              3 LOAD_FAST                1 (val)
              6 BINARY_SUBSCR       
              7 RETURN_VALUE  

It will come in handy if you need to set a default value while looking up a dictionary. This lowers the

 if key in dic:
      val = dic[key]
      val = def_val

val = dic.get(key,def val) to a single line

If you wish to return a KeyError that says the key isn’t available, use this method. Returning a default value also raises the possibility that the default value is a key!

Yes! The __missing__ must be implemented in a dict subclass.

A sample program can be found here.

class MyDict(dict):
    def __missing__(self, key):
        return None

A brief demonstration could be useful.

>>> my_d = MyDict({1:2,2:3})
>>> my_d[1]
>>> my_d[3]
>>> repr(my_d[3])

Answered by Bhargav Rao

Solution #3

A second optional value is passed to get. This value will be returned if the supplied key does not exist in your dictionary.

dictionary = {"Name": "Harry", "Age": 17}
dictionary.get('Year', 'No available data')
>> 'No available data'

If the second parameter is omitted, None will be returned.

Nonexistent keys will generate a KeyError if you use indexing like dictionary[‘Year’].

Answered by FallenAngel

Solution #4

I will give a practical example in scraping web data using python, a lot of the times you will get keys with no values, in those cases you will get errors if you use dictionary[‘key’], whereas dictionary.get(‘key’, ‘return_otherwise’) has no problems.

If you’re trying to grab a single value from a list, I’d recommend using “.join(list) rather than list[0].

hope it helps.

[Edit] Here’s an example from the real world:

Let’s say you’re calling an API and getting a JOSN file to parse. The first JSON file looks like this:

{"bids":{"id":16210506,"submitdate":"2011-10-16 15:53:25","submitdate_f":"10\/16\/2011 at 21:53 CEST","submitdate_f2":"p\u0159ed 2 lety","submitdate_ts":1318794805,"users_id":"2674360","project_id":"1250499"}}

This is how the second JOSN looks:

{"bids":{"id":16210506,"submitdate":"2011-10-16 15:53:25","submitdate_f":"10\/16\/2011 at 21:53 CEST","submitdate_f2":"p\u0159ed 2 lety","users_id":"2674360","project_id":"1250499"}}

The “submitdate ts” key is missing in the second JSON, which is rather common in any data structure.

So, if you’re trying to access the value of that key in a loop, can you use the following syntax:

for item in API_call:
    submitdate_ts = item["bids"]["submitdate_ts"]

You could, but it will give you a traceback error for the second JSON line, because the key simply doesn’t exist.

The following would be an appropriate approach to code this:

for item in API_call:
    submitdate_ts = item.get("bids", {'x': None}).get("submitdate_ts")

‘x’: None is present to prevent an error on the second level. If you’re scraping, you can, of course, add extra fault tolerance to the code. As with specifying an if condition first,

Answered by kevin

Solution #5

A gotcha to be aware of when using . get():

Even if a default value is provided, the.get() function will return None if the dictionary contains the key used in the call to.get() and its value is None.

For instance, consider the following results: None, rather than the expected ‘alt value’:

d = {'key': None}
assert None is d.get('key', 'alt_value')

The second result of.get() is only returned if the specified key is not in the dictionary, not if the call’s return value is None.

Answered by user1847

Post is based on