How to get nested dictionary key value with .get()

27,315

Solution 1

dict.get accepts additional default parameter. The value is returned instead of None if there's no such key.

print myDict.get('key1', {}).get('attr3')

Solution 2

There is a very nice blog post from Dan O'Huiginn on the topic of nested dictionaries. He ultimately suggest subclassing dict with a class that handles nesting better. Here is the subclass modified to handle your case trying to access keys of non-dict values:

class ndict(dict):
     def __getitem__(self, key):
         if key in self: return self.get(key)
         return self.setdefault(key, ndict())

You can reference nested existing keys or ones that don't exist. You can safely use the bracket notation for access rather than .get(). If a key doesn't exist on a NestedDict object, you will get back an empty NestedDict object. The initialization is a little wordy, but if you need the functionality, it could work out for you. Here are some examples:

In [97]: x = ndict({'key1': ndict({'attr1':1, 'attr2':2})})

In [98]: x
Out[98]: {'key1': {'attr1': 1, 'attr2': 2}}

In [99]: x['key1']
Out[99]: {'attr1': 1, 'attr2': 2}

In [100]: x['key1']['key2']
Out[100]: {}

In [101]: x['key2']['key2']
Out[101]: {}

In [102]: x['key1']['attr1']
Out[102]: 1

Solution 3

Use exceptions:

try:
    print myDict['key1']['attr3']
except KeyError:
    print "Can't find my keys"
Share:
27,315

Related videos on Youtube

alphanumeric
Author by

alphanumeric

Updated on March 09, 2022

Comments

  • alphanumeric
    alphanumeric about 2 years

    With a simple dictionary like:

    myDict = {'key1':1, 'key2':2}
    

    I can safely use:

    print myDict.get('key3')
    

    and even while 'key3' is not existent no errors will be thrown since .get() still returns None.

    Now how would I achieve the same simplicity with a nested keys dictionary:

    myDict={}
    myDict['key1'] = {'attr1':1,'attr2':2}
    

    The following will give a KeyError:

    print myDict.get('key1')['attr3']
    

    This will go through:

    print myDict.get('key1').get('attr3')
    

    but it will fail with adn AttributeError: 'NoneType' object has no attribute 'get':

    print myDict.get('key3').get('attr1')
    
  • alphanumeric
    alphanumeric about 10 years
    Thanks! Great to know!
  • Captain Lepton
    Captain Lepton almost 7 years
    Now why the hell couldn't I have thought of that?!?
  • dreftymac
    dreftymac over 4 years
  • Pavel Vergeev
    Pavel Vergeev over 4 years
    Note that myDict.get('key1', {}) can still return None if myDict['key1'] = None is set explicitly. I would actually recommend this approach.
  • falsetru
    falsetru over 4 years
    @PavelVergeev, My answer, and the other answer you linked both will raise TypeError: 'NoneType' object has no attribute '__getitem__' in such case. ;)