Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Return path of all JSON elements that match string

I'm trying to logically traverse a JSON in Python and return the path of any String value that equals a value. I'm trying to traverse it recursively, but if multiple elements match the comparison, it only returns he first:

test_json = {
    "a": {
        "b": {
            "c": {
                "d": "foo"
            }
        }
    },
    "1": {
        "2": {
            "3": "bar"
        }
    },
    "a1" : "foo"
}

def searchDict(d, path):
    for k,v in d.iteritems():
        if isinstance(v, dict):
            path.append(k)
            return searchDict(v, path)
        else:
            if v == "foo":
                path.append(k)
                path.append(v)
                return path

print searchDict(test_json, [])

I want this to have the capacity to return something like:

a -> b -> c -> d -> foo
a1 -> foo

But instead it only iterates through the first sub-dictionary:

['a', 'b', 'c', 'd', 'foo']

This is probably easier than I'm making it, just having trouble logically solving it. Any ideas?

like image 650
ev0lution37 Avatar asked Apr 11 '26 23:04

ev0lution37


1 Answers

What a good question. You are actually two tiny bits away from solving it yourself.

  1. appending to path variable will cause that the same variable will be used in all recursive calls. Using path + [k] will solve this. If it's hard to get try to use your code and print out path at the beginning of the searchdict function
  2. You are correctly using for cycle to iterate over the json file. However you are also returning inside the forcycle, which will stop it and other possibilities won't get explored. Either print out the results, add it to a result field or use python's generator to get the results

check out my modified working code. tried to make as little changes into your code so it's easy to understand.

test_json = {
    "a": {
        "b": {
            "c": {
                "d": "foo"
            }
        }
    },
    "1": {
        "2": {
            "3": "bar"
        }
    },
    "a1" : "foo"
}

def searchDict(d, path):
    for k,v in d.iteritems():
        if isinstance(v, dict):
            searchDict(v, path + [k])
        else:
            if v == "foo":
                print(path + [k] + [v])


searchDict(test_json, [])
like image 71
Martin Gottweis Avatar answered Apr 14 '26 12:04

Martin Gottweis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!