By stensootla


2012-06-14 21:10:39 8 Comments

Today, I came across the dict method get which, given a key in the dictionary, returns the associated value.

For what purpose is this function useful? If I wanted to find a value associated with a key in a dictionary, I can just do dict[key], and it returns the same thing:

dictionary = {"Name": "Harry", "Age": 17}
dictionary["Name"]
dictionary.get("Name")

9 comments

@U9-Forward 2018-11-07 05:35:15

  • dict.get will default return nothing if the key doesn't exist, but if you put second argument of it, it will return that if the key does not exist.

  • OTOH dict[key] will raise KeyError if key does not exist.

Here is an example (read comments):

>>> d={'a':[1,2,3],'b':[4,5,6]} # Create a dictionary
>>> d['c'] # Hoops, error key does not exist
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    d['c']
KeyError: 'c'
>>> d.get('c') # no error because of `get`, so nothing returned
>>> print(d.get('c')) # i print it, oh `None` is the output
None
>>> d.get('c',100) # Okay now i set second argument's value to `100`, hoopa output is `100`
100
>>> d['a'] # Works, key exist
[1, 2, 3]
>>> d.get('a') # work too, key exist
[1, 2, 3]

@JawSaw 2017-12-15 02:06:01

Why dict.get(key) instead of dict[key]?

0. Summary

Comparing to dict[key], dict.get provides a fallback value when looking up for a key.

1. Definition

get(key[, default]) 4. Built-in Types — Python 3.6.4rc1 documentation

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.

d = {"Name": "Harry", "Age": 17}
In [4]: d['gender']
KeyError: 'gender'
In [5]: d.get('gender', 'Not specified, please add it')
Out[5]: 'Not specified, please add it'

2. Problem it solves.

If without default value, you have to write cumbersome codes to handle such an exception.

def get_harry_info(key):
    try:
        return "{}".format(d[key])
    except KeyError:
        return 'Not specified, please add it'
In [9]: get_harry_info('Name')
Out[9]: 'Harry'
In [10]: get_harry_info('Gender')
Out[10]: 'Not specified, please add it'

As a convenient solution, dict.get introduces an optional default value avoiding above unwiedly codes.

3. Conclusion

dict.get has an additional default value option to deal with exception if key is absent from the dictionary

@jetpack_guy 2017-09-04 23:19:24

For what purpose is this function useful?

One particular usage is counting with dictionary. Let's assume you want to count a number of occurrences of each element in a given list. The common way to do so is to make a dictionary where keys are elements and values are the number of occurrences.

fruits = ['apple', 'banana', 'peach', 'apple', 'pear']
d = {}
for fruit in fruits:
    if fruit not in d:
        d[fruit] = 0
    d[fruit] += 1

Using the .get() method you can make this code more compact and clear:

for fruit in fruits:
      d[fruit] = d.get(fruit, 0) + 1

@hackartist 2012-06-14 21:12:27

The purpose is that you can give a default value if the key is not found, which is very useful

dictionary.get("Name",'harry')

@unutbu 2012-06-14 21:12:12

It allows you to provide a default value if the key is missing:

dictionary.get("bogus", default_value)

returns default_value (whatever you choose it to be), whereas

dictionary["bogus"]

would raise a KeyError.

If omitted, default_value is None, such that

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

returns None just like

dictionary.get("bogus", None)

would.

@Niklas B. 2012-06-14 21:12:52

Which is actually the same as dictionary.get("bogus"). I'm sure you're aware of that but it might be interesting to other readers :)

@unutbu 2012-06-14 21:13:44

Thanks, @Niklas B.

@Gareth Latty 2012-06-14 21:16:16

@John No, the value will be returned, but it will not modify the dict. Note that if you are using this functionality a lot, a collections.defaultdict might be more appropriate.

@Niklas B. 2012-06-14 21:16:56

@John: What you describe is what setdefault does (a very similar method that behaves just like get but also saves the value).

@Niklas B. 2012-06-14 21:18:30

I edited the answer to make this absolutely clear. Hope you don't mind, @unutbu.

@Tjorriemorrie 2015-02-05 12:46:54

It's very useful in reinforcement learning that requires randomized initialization: e.g. q_sa = q.get((s, action), random())

@Algorithmatic 2015-12-04 21:57:53

Would this be the same as dictionary.get("bogus") or my_default? I've seen people use it in some cases and I was wondering if there's any advantage of using one instead of the other (other than readability)

@unutbu 2015-12-04 22:22:47

@MustafaS: If "bogus" is a key in dictionary and dictionary.get("bogus") returns a value which evaluates to False in a boolean context (i.e. a Falsey value), such as 0 or an empty string, '', then dictionary.get("bogus") or my_default would evaluate to my_default whereas dictionary.get("bogus", my_default) would return the Falsey value. So no, dictionary.get("bogus") or my_default is not equivalent to dictionary.get("bogus", my_default). Which to use depends on the behavior you desire.

@unutbu 2015-12-04 22:27:59

@MustafaS: For example, suppose x = {'a':0}. Then x.get('a', 'foo') returns 0 but x.get('a') or 'foo' returns 'foo'.

@Algorithmatic 2015-12-05 19:52:15

Ah yes forgot about the 'False/0' case. Thanks!

@Aart Goossens 2016-02-17 10:33:06

One possible caveat when using dictionary.get('key'): It can be confusing if values in the dictionary are None. Without specifying the return value (second optional argument) there is no way to verify if the key didn't exist or if its value is None. In this specific case I would consider using try-except-KeyError.

@Tom Stambaugh 2018-09-14 19:22:59

It's worth noting that the expression to specify the default value is evaluated in the "get" call, and is therefore evaluated on each access. A classic alternative (using either a KeyError handler or a predicate) is to evaluate the default value only if the key is missing. This allows a closure/lambda to be created once and evaluated on any missing key.

@Muthuvel 2016-08-25 07:02:45

Based on usage should use this get method.

Example1

In [14]: user_dict = {'type': False}

In [15]: user_dict.get('type', '')

Out[15]: False

In [16]: user_dict.get('type') or ''

Out[16]: ''

Example2

In [17]: user_dict = {'type': "lead"}

In [18]: user_dict.get('type') or ''

Out[18]: 'lead'

In [19]: user_dict.get('type', '')

Out[19]: 'lead'

@kevin 2015-07-11 23:52:10

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.

Similarly, I would use ''.join(list) as opposed to list[0] if you try to capture a single value from a list.

hope it helps.

[Edit] Here is a practical example:

Say, you are calling an API, which returns a JOSN file you need to parse. The first JSON looks like following:

{"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"}}

The second JOSN is 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","users_id":"2674360","project_id":"1250499"}}

Note that the second JSON is missing the "submitdate_ts" key, which is pretty normal in any data structure.

So when you try to access the value of that key in a loop, can you call it with the following:

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 appropriate way of coding this, could be the following:

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

{'x': None} is there to avoid the second level getting an error. Of course you can build in more fault tolerance into the code if you are doing scraping. Like first specifying a if condition

@Mawg 2016-03-03 09:49:28

A good answer, posted before any of the others, which would have been upvoted more, and probably accepted, if you had posted some code examples (+1 from me, though)

@kevin 2016-08-13 22:06:52

@Mawg I recently had a scraping project for my research. It was calling an API and parsing JSON files basically. I had my RA do it. One of the key issues he had was calling the key directly, when many keys are actually missing. I will post an example in the text above.

@Mawg 2016-08-14 11:55:08

Another upvote, Kevin, for helping others

@bluppfisk 2017-12-03 16:56:23

thanks for tackling the multi-dimensional aspect of this! Sounds like you can even just do {} instead of {'x': None}

@Rambatino 2018-06-26 13:20:29

so much JOSN, who knew?!

@Bhargav Rao 2016-06-22 12:48:42

What is the dict.get() method?

As already mentioned the get method contains an additional parameter which indicates the missing value. From the documentation

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.

An example can be

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

Are there speed improvements anywhere?

As mentioned here,

It seems that all three approaches now exhibit similar performance (within about 10% of each other), more or less independent of the properties of the list of words.

Earlier get was considerably slower, However now the speed is almost comparable along with the additional advantage of returning the default value. But to clear all our queries, we can test on a fairly large list (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 timing these two functions using timeit

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

As we can see the lookup is faster than the get as there is no function lookup. This can be seen through dis

>>> 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  

Where will it be useful?

It will be useful whenever you want to provide a default value whenever you are looking up a dictionary. This reduces

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

To a single line, val = dic.get(key,def_val)

Where will it be NOT useful?

Whenever you want to return a KeyError stating that the particular key is not available. Returning a default value also carries the risk that a particular default value may be a key too!

Is it possible to have get like feature in dict['key']?

Yes! We need to implement the __missing__ in a dict subclass.

A sample program can be

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

A small demonstration can be

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

@Apollo Data 2017-03-05 17:59:24

Gold standard of StackOverflow answers!

@Abhijeet 2017-04-07 06:24:16

@TitanFighter 2017-09-16 18:05:50

One more good test would be if k in dict and dict[k]: vs if dict.get(k):. This covers the situation when we need to check if key exists, and if 'yes' - what value?, something like: dict = {1: '', 2: 'some value'}.

@Kresimir 2018-05-08 10:34:14

Please remember that default value gets evaluated regardless of the value being in dictionary, so instead of dictionary.get(value, long_function()) one might consider using dictionary.get(value) or long_function()

@Bhargav Rao 2018-05-10 07:56:23

Ah @Kresimir, true. I did get that question in one of the interviews which I faced (I did not know about it when I had originally posted this answer). Thanks for reminding me about it.

@FallenAngel 2012-06-14 21:16:38

get takes a second optional value. If the specified key does not exist in your dictionary, then this value will be returned.

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

If you do not give the second parameter, None will be returned.

If you use indexing as in dictionary['Year'], nonexistent keys will raise KeyError.

Related Questions

Sponsored Content

43 Answered Questions

[SOLVED] How to merge two dictionaries in a single expression?

9 Answered Questions

21 Answered Questions

[SOLVED] Check if a given key already exists in a dictionary

  • 2009-10-21 19:05:09
  • Mohan Gulati
  • 2724431 View
  • 2583 Score
  • 21 Answer
  • Tags:   python dictionary

14 Answered Questions

[SOLVED] Add new keys to a dictionary?

  • 2009-06-21 22:07:39
  • lfaraone
  • 2815903 View
  • 2171 Score
  • 14 Answer
  • Tags:   python dictionary

49 Answered Questions

[SOLVED] Sort a Map<Key, Value> by values

10 Answered Questions

[SOLVED] Calling a function of a module by using its name (a string)

  • 2008-08-06 03:36:08
  • ricree
  • 551583 View
  • 1380 Score
  • 10 Answer
  • Tags:   python object

14 Answered Questions

[SOLVED] Running shell command and capturing the output

14 Answered Questions

[SOLVED] How to return multiple values from a function?

11 Answered Questions

[SOLVED] Use of *args and **kwargs

  • 2010-08-03 08:28:07
  • MacPython
  • 799736 View
  • 1280 Score
  • 11 Answer
  • Tags:   python args kwargs

8 Answered Questions

[SOLVED] Getting the class name of an instance?

Sponsored Content