Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use python "get()" for keys deeper than first level of dictionary keys?

I have a python dictionary that has more than 2 levels, something like this:

dict = {'keyA_1':'valueA_1', 'keyB_1': {'keyB_2':{'keyB_3':'valueB_3'}}}

I wish to extract the value of 'keyA_1' and 'keyB_3'. However, in my code, I do not want to use a bunch of try/except KeyError for error checking as I have thousands of key-value pairs. Instead, if the key does not exist, simply returns None. One solution I found is to use python get(). This works nicely but only for first level key-value pair.

For example, if 'keyA_1' does not exist

dict.get('keyA_1')

would return None

But if 'keyB_3' does not exist

dict.get('keyB_1').get('keyB_2').get('keyB_3')

would return AttributeError: 'NoneType' object has no attribute 'get' instead of None

It would be great to simply do the same for 'keyB_3' where it returns the value if all parent keys and its key exist else return None. Any suggestion?

like image 845
return 0 Avatar asked May 23 '16 03:05

return 0


2 Answers

You can pass a default value as the second argument to dict.get(), like this:

dict.get('keyB_1', {}).get('keyB_2', {}).get('keyB_3')
like image 54
Tarun Behal Avatar answered Nov 02 '22 07:11

Tarun Behal


The accepted answer works, but is way too much inline code. Here's a version that's easy to use:

# Usage: dot_get(mydict, 'some.deeply.nested.value', 'my default')
def dot_get(_dict, path, default=None):
  for key in path.split('.'):
    try:
      _dict = _dict[key]
    except KeyError:
      return default
  return _dict

Easiest use: retrieved_value = dot_get('some.deeply.nested.value')

like image 42
vaughnkoch Avatar answered Nov 02 '22 06:11

vaughnkoch