You need a recursive search.
You can define a function to deeply search in your input json:
def find_in_obj(obj, condition, path=None):
if path is None:
path = []
# In case this is a list
if isinstance(obj, list):
for index, value in enumerate(obj):
new_path = list(path)
new_path.append(index)
for result in find_in_obj(value, condition, path=new_path):
yield result
# In case this is a dictionary
if isinstance(obj, dict):
for key, value in obj.items():
new_path = list(path)
new_path.append(key)
for result in find_in_obj(value, condition, path=new_path):
yield result
if condition == key:
new_path = list(path)
new_path.append(key)
yield new_path
We can then use the example JSON in this similar SO question to test the recursive search:
In [15]: my_json = { "id" : "abcde",
....: "key1" : "blah",
....: "key2" : "blah blah",
....: "nestedlist" : [
....: { "id" : "qwerty",
....: "nestednestedlist" : [
....: { "id" : "xyz",
....: "keyA" : "blah blah blah" },
....: { "id" : "fghi",
....: "keyZ" : "blah blah blah" }],
....: "anothernestednestedlist" : [
....: { "id" : "asdf",
....: "keyQ" : "blah blah" },
....: { "id" : "yuiop",
....: "keyW" : "blah" }] } ] }
Let's find every instance of the key 'id' and return the full path that gets us there:
In [16]: for item in find_in_obj(my_json, 'id'):
....: print item
....:
['nestedlist', 0, 'nestednestedlist', 0, 'id']
['nestedlist', 0, 'nestednestedlist', 1, 'id']
['nestedlist', 0, 'id']
['nestedlist', 0, 'anothernestednestedlist', 0, 'id']
['nestedlist', 0, 'anothernestednestedlist', 1, 'id']
['id']