'Get parents keys from nested dictionary

From the following nested dictionary, how can I get every parent dictionary key of 'value4ac'? By starting the 'value4ac' value, I want to get 'key4', 'key4a', 'Key4ac'.

example_dict = { 'key1' : 'value1',
                 'key2' : 'value2',
                 'key3' : { 'key3a': 'value3a' },
                 'key4' : { 'key4a': { 
                                         'key4aa': 'value4aa',
                                         'key4ab': 'value4ab',
                                         'key4ac': 'value4ac'
                                     },
                            'key4b': 'value4b'
                           }
                   } 


Solution 1:[1]

What if your dictionary contains lists too?

Here's a more broad variant of @mgilson 's solution, suitable for JSON:

example_dict_with_list = { 'key1' : 'value1',
                           'key2' : 'value2',
                           'key3' : { 'key3a': 'value3a' },
                           'key4' : { 'key4a': [{ 'key4aa': 'value4aa',
                                                  'key4ab': 'value4ab',
                                                  'key4ac': 'value4ac'}],
                                      'key4b': 'value4b'}
                          }

def breadcrumb(json_dict_or_list, value):
  if json_dict_or_list == value:
    return [json_dict_or_list]
  elif isinstance(json_dict_or_list, dict):
    for k, v in json_dict_or_list.items():
      p = breadcrumb(v, value)
      if p:
        return [k] + p
  elif isinstance(json_dict_or_list, list):
    lst = json_dict_or_list
    for i in range(len(lst)):
      p = breadcrumb(lst[i], value)
      if p:
        return [str(i)] + p

print(
    breadcrumb(example_dict_with_list, 'value4aa')
)

Which returns

['key4', 'key4a', '0', 'key4aa', 'value4aa']

Bonus

If you need to print it out nicely, like a string of breadcrums, do

print(
  ' > '.join(
    breadcrumb(example_dict, 'value4aa')
  )
)

Which will return

'key4 > key4a > 0 > key4aa > value4aa'

Solution 2:[2]

You can use a NestedDict.

>>> from ndicts.ndicts import NestedDict
>>> example_dict = { 'key1' : 'value1',
...                  'key2' : 'value2',
...                  'key3' : { 'key3a': 'value3a' },
...                  'key4' : { 'key4a': {
...                                          'key4aa': 'value4aa',
...                                          'key4ab': 'value4ab',
...                                          'key4ac': 'value4ac'
...                                      },
...                             'key4b': 'value4b'
...                            }
...                    }
>>> nd = NestedDict(example_dict)
>>> for key, value in nd.items():
...     if value == "value4ac":
...             print(key)
...
('key4', 'key4a', 'key4ac')

To install ndicts

pip install ndicts

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 KiriSakow
Solution 2 edd313