Return a default value if a dictionary key is not available

PythonDictionaryKeyNonetype

Python Problem Overview


I need a way to get a dictionary value if its key exists, or simply return None, if it does not.

However, Python raises a KeyError exception if you search for a key that does not exist. I know that I can check for the key, but I am looking for something more explicit. Is there a way to just return None if the key does not exist?

Python Solutions


Solution 1 - Python

You can use dict.get()

value = d.get(key)

which will return None if key is not in d. You can also provide a different default value that will be returned instead of None:

value = d.get(key, "empty")

Solution 2 - Python

Wonder no more. It's built into the language.

>>> help(dict)

Help on class dict in module builtins:

class dict(object)
 |  dict() -> new empty dictionary
 |  dict(mapping) -> new dictionary initialized from a mapping object's
 |      (key, value) pairs
...
 |  
 |  get(...)
 |      D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
 |  
...

Solution 3 - Python

Use dict.get

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

Solution 4 - Python

You should use the get() method from the dict class

d = {}
r = d.get('missing_key', None)

This will result in r == None. If the key isn't found in the dictionary, the get function returns the second argument.

Solution 5 - Python

If you want a more transparent solution, you can subclass dict to get this behavior:

class NoneDict(dict):
    def __getitem__(self, key):
        return dict.get(self, key)

>>> foo = NoneDict([(1,"asdf"), (2,"qwerty")])
>>> foo[1]
'asdf'
>>> foo[2]
'qwerty'
>>> foo[3] is None
True

Solution 6 - Python

I usually use a defaultdict for situations like this. You supply a factory method that takes no arguments and creates a value when it sees a new key. It's more useful when you want to return something like an empty list on new keys (see the examples).

from collections import defaultdict
d = defaultdict(lambda: None)
print d['new_key']  # prints 'None'

Solution 7 - Python

You could use a dict object's get() method, as others have already suggested. Alternatively, depending on exactly what you're doing, you might be able use a try/except suite like this:

try:
   <to do something with d[key]>
except KeyError:
   <deal with it not being there>

Which is considered to be a very "Pythonic" approach to handling the case.

Solution 8 - Python

A one line solution would be:

item['key'] if 'key' in item else None

This is useful when trying to add dictionary values to a new list and want to provide a default:

eg.

row = [item['key'] if 'key' in item else 'default_value']

Solution 9 - Python

As others have said above, you can use get().

But to check for a key, you can also do:

d = {}
if 'keyname' in d:

    # d['keyname'] exists
    pass

else:

    # d['keyname'] does not exist
    pass

Solution 10 - Python

For those using the dict.get technique for nested dictionaries, instead of explicitly checking for every level of the dictionary, or extending the dict class, you can set the default return value to an empty dictionary except for the out-most level. Here's an example:

my_dict = {'level_1': {
             'level_2': {
                  'level_3': 'more_data'
                  }
              }
           }
result = my_dict.get('level_1', {}).get('level_2', {}).get('level_3')
# result -> 'more_data'
none_result = my_dict.get('level_1', {}).get('what_level', {}).get('level_3')
# none_result -> None

WARNING: Please note that this technique only works if the expected key's value is a dictionary. If the key what_level did exist in the dictionary but its value was a string or integer etc., then it would've raised an AttributeError.

Solution 11 - Python

I was thrown aback by what was possible in python2 vs python3. I will answer it based on what I ended up doing for python3. My objective was simple: check if a json response in dictionary format gave an error or not. My dictionary is called "token" and my key that I am looking for is "error". I am looking for key "error" and if it was not there setting it to value of None, then checking is the value is None, if so proceed with my code. An else statement would handle if I do have the key "error".

if ((token.get('error', None)) is None):
    do something

Solution 12 - Python

You can use try-except block

try:
    value = dict['keyname']

except IndexError:
    value = None

Solution 13 - Python

If you can do it with False, then, there's also the hasattr built-in funtion:

e=dict()
hasattr(e, 'message'):
>>> False
  

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSpyrosView Question on Stackoverflow
Solution 1 - PythonTim PietzckerView Answer on Stackoverflow
Solution 2 - PythonJohn La RooyView Answer on Stackoverflow
Solution 3 - PythonDaenythView Answer on Stackoverflow
Solution 4 - PythondusktreaderView Answer on Stackoverflow
Solution 5 - PythonBjörn PollexView Answer on Stackoverflow
Solution 6 - PythonjobView Answer on Stackoverflow
Solution 7 - PythonmartineauView Answer on Stackoverflow
Solution 8 - Pythonimapotatoe123View Answer on Stackoverflow
Solution 9 - PythonMarek PView Answer on Stackoverflow
Solution 10 - PythoneaydinView Answer on Stackoverflow
Solution 11 - PythonFastGTRView Answer on Stackoverflow
Solution 12 - PythonVarmiloView Answer on Stackoverflow
Solution 13 - PythonEvhzView Answer on Stackoverflow