return 0
return 0

Reputation: 4366

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?

Upvotes: 7

Views: 6273

Answers (2)

vaughnkoch
vaughnkoch

Reputation: 1779

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

Upvotes: 4

Tarun Behal
Tarun Behal

Reputation: 918

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

Upvotes: 18

Related Questions