Find a key inside a deeply nested dictionary

Question:

I have a lot of nested dictionaries, I am trying to find a certain key nested inside somewhere.

e.g. this key is called “fruit”. How do I find the value of this key?

Asked By: TIMEX

||

Answers:

(Making some wild guesses about your data structure…)

Do it recursively:

def findkey(d, key):
    if key in d: return d[key]
    for k,subdict in d.iteritems():
        val = findkey(subdict, key)
        if val: return val
Answered By: Marcelo Cantos

Just traverse the dictionary and check for the keys (note the comment in the bottom about the “not found” value).

def find_key_recursive(d, key):
  if key in d:
    return d[key]
  for k, v in d.iteritems():
    if type(v) is dict: # Only recurse if we hit a dict value
      value = find_key_recursive(v, key)
      if value:
        return value
  # You may want to return something else than the implicit None here (and change the tests above) if None is an expected value
Answered By: Håvard S

@HÃ¥vard’s recursive solution is probably going to be OK… unless the level of nesting is too high, and then you get a RuntimeError: maximum recursion depth exceeded. To remedy that, you can use the usual technique for recursion removal: keep your own stack of items to examine (as a list that’s under your control). I.e.:

def find_key_nonrecursive(adict, key):
  stack = [adict]
  while stack:
    d = stack.pop()
    if key in d:
      return d[key]
    for k, v in d.iteritems():
      if isinstance(v, dict):
        stack.append(v)

The logic here is quite close to the recursive answer (except for checking for dict in the right way;-), with the obvious exception that the recursive calls are replaced with a while loop and .pop and .append operations on the explicit-stack list, stack.

Answered By: Alex Martelli

Almost 11 years later… based on Alex Martelli answer with slight modification, for Python 3 and lists:

def find_key_nonrecursive(adict, key):
    stack = [adict]
    while stack:
        d = stack.pop()
        if key in d:
            return d[key]
        for v in d.values():
            if isinstance(v, dict):
                stack.append(v)
            if isinstance(v, list):
                stack += v
Answered By: Cristian

I have written a handy library for this purpose.

I am iterating over ast of the dict and trying to check if a particular key is present or not.

Do check this out. https://github.com/Agent-Hellboy/trace-dkey

An example from README

>>> from trace_dkey import trace
>>> l={'a':{'b':{'c':{'d':{'e':{'f':1}}}}}}
>>> print(trace(l,'f'))
[['a', 'b', 'c', 'd', 'e', 'f']]

Now you can query it as l['a']['b']['c']['d']['e']['f']

>>> l['a']['b']['c']['d']['e']['f']
1
Answered By: Prince Roshan
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.