0

I have a nested dictionary that contains dictionaries of key value pairs pulled from json. For instance a nested dictionary called 'some_dict':

{1: {'address': 'some address', 'status': 'some status', 'name': 'some name'},
 2: {'address': 'some other address', 'status': 'some other status', 'name': 'some other name'}}

I need to search this nested dictionary for a specific value of key 'status', and when it matches, return all the values of that dictionary. However, I am continually receiving a key error in my implementation, and I can't figure out why.

# Based on this answer: https://stackoverflow.com/questions/9807634/find-all-occurrences-of-a-key-in-nested-dictionaries-and-lists

def has_key_value(data, target):
    for key, value in data.items():
        if isinstance(value, dict):
            yield from has_key_value(value, target)
        elif key == target:
            return true

for x in range(1, len(some_dict)):
    if has_key_value(x, 'some status'):
        #print the dictionary

I've gotten this far, but I can't for the life of me figure out how to return the contents of the dictionary in the nested some_dict. I have tried several things and finally came to this which sort of works:

for x in range(1, len(some_dict)):
    if has_key_value(x, 'some status'):
        print(some_dict[x])

Except after the first 3 dictionaries being printed it throws a 'KeyError: 4' error. I have checked that all the dictionaries within some_dict are identical in their schema so I can't figure out why the error. Thoughts?

Fresh
  • 87
  • 7
  • 2
    Shouldn't it be `if value == target:`? – Barmar Sep 09 '20 at 22:57
  • Why are you using `yield` instead of `return`? – Barmar Sep 09 '20 at 22:59
  • typos from what I had before when it was returning a boolean. It is corrected – Fresh Sep 09 '20 at 23:01
  • That error sounds like it's coming from the top level dictionary. You've excepted away most of its contents, but I'd guess you have keys `1`, `2` and `3`, but `4` is skipped (though there are more keys later). If you don't need the numbers, I'd suggest looping over `some_dict.values()` rather than over a range. Or since your search function is recursive, just calling it on `some_dict` directly, without an outer loop. – Blckknght Sep 09 '20 at 23:01
  • Do you really have multiple levels of nesting that you need to recurse through? – Barmar Sep 09 '20 at 23:01
  • Why are you looping over all the items in the dictionary, if you only need to check the `status` key? – Barmar Sep 09 '20 at 23:02

1 Answers1

3

You seem to be making this much more complicated than necessary. You don't seem to have multiple levels of nesting, so you don't have to recurse. And you only care of the status key matches the given value, not any other keys.

for d in some_dict.values():
    if d['status'] == 'some status':
        print(d)
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Yup... you are 100% correct. I over complicated that. I spent so much time moving things around that I just over did it... thank you, Im an idiot. – Fresh Sep 09 '20 at 23:08