bguan2020
bguan2020

Reputation: 103

Parsing through nested JSON keys

I have a JSON file that looks like this:

data = {
    "x": {
        "y": {
            "key": {

            },
            "w": {

            }
}}}

And have converted it into a dict in python to them parse through it to look for keys, using the following code:

entry = input("Search JSON for the following: ") //search for "key"
if entry in data:
  print(entry)
else:
  print("Not found.")

However, even when I input "key" as entry, it still returns "Not found." Do I need to control the depth of data, what if I don't know the location of "key" but still want to search for it.

Upvotes: 1

Views: 1378

Answers (2)

neutrino_logic
neutrino_logic

Reputation: 1299

Here's an approach which allows you to collect all the values from a nested dict, if the keys are repeated at different levels of nesting. It's very similar to the above answer, just wrapped in a function with a nonlocal list to hold the results:

def foo(mydict, mykey):
    result = []
    num_recursive_calls = 0

    def explore(mydict, mykey):
        #nonlocal result      #allow successive recursive calls to write to list
                              #actually this is unnecessary in this case! Here 
                              #is where we would need it, for a call counter: 
        nonlocal num_recursive_calls
        num_recursive_calls += 1
        for key in mydict.keys():   #get all keys from that level of nesting
            if mykey == key:
                print(f"Found {key}")
                result.append({key:mydict[key]})

            elif isinstance(mydict.get(key), dict):
                print(f"Found nested dict under {key}, exploring")
                explore(mydict[key], mykey)

    explore(mydict, mykey)
    print(f"explore called {num_recursive_calls} times") #see above
    return result

For example, with

data = {'x': {'y': {'key': {}, 'w': {}}}, 'key': 'duplicate'}

This will return:

[{'key': {}}, {'key': 'duplicate'}] 

Upvotes: 1

Mark
Mark

Reputation: 92461

Your method is not working because key is not a key in data. data has one key: x. So you need to look at the dictionary and see if the key is in it. If not, you can pass the next level dictionaries back to the function recursively. This will find the first matching key:

data = {
    "x": {
        "y": {
            "key": "some value",
            "w": {}
}}}

key = "key"

def findValue(key, d):
    if key in d:
        return d[key]
    for v in d.values():
        if isinstance(v, dict):
            found = findValue(key, v)
            if found is not None:
                return found

findValue(key, data)  
# 'some value'

It will return None if your key is not found

Upvotes: 3

Related Questions