You need to search a tree. Here's the easiest way to do it.
It could be enhanced - for example, it is better to use None as default arg value instead of some object. Also, this is depth first search - you may want to get only one result, and that's when width first search is better (read about both those terms on wikipedia if you don't know them).
import json
example_json = """{
"someList" : [
{
"x": {
"y": {
"z": "Some value"
}
}
},
{
"x": {
"y": {
"a": "Wrong key"
}
}
}
]
}
"""
struct = json.loads(example_json)
def find_all_with_key(wanted_key, tree, path=tuple()):
if isinstance(tree, list):
for idx, el in enumerate(tree):
yield from find_all_with_key(wanted_key, el, path+(idx,))
elif isinstance(tree, dict):
for k in tree:
if k == wanted_key:
yield path +(k, )
# you can add order of width-search by sorting result of tree.items()
for k, v in tree.items():
yield from find_all_with_key(wanted_key, v, path+(k,))
def retrieve(tree, path):
for p in path:
tree = tree[p]
return tree
result = list(find_all_with_key("z", struct))
expected = [ ("someList", 0, "x", "y", "z") ]
assert result == expected
assert retrieve(struct, result[0]) == "Some value"