I am trying to find all the full path for specific key. I tried with recursion, i can able to get the values, but i can't able to track the path using my code. Any Help will definitely useful for me.
Input:
{
"id": ["0001"],
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters": {
"batter": {
"id": ["1001"],
"type": "Regular"
}
},
"topping": [
{
"id": ["5001"],
"type": "None"
},
{
"id": ["5002"],
"type": "Glazed"
}
]
}
Expected Output:
[
{"id":["0001"]},
{"batters.batter.id":["1001"]},
{"topping[0].id":["5001"]},
{"topping[0].id":["5002"]}
]
Following code is i have used for get the values, but it doesn't helped me.
def json_extract(obj, key):
"""Recursively fetch values from nested JSON."""
arr = []
def extract(obj, arr, key):
"""Recursively search for values of key in JSON tree."""
if isinstance(obj, dict):
for k, v in obj.items():
if isinstance(v, (dict)):
extract(v, arr, key)
elif k == key:
arr.append(v)
elif isinstance(obj, list):
for item in obj:
extract(item, arr, key)
return arr
values = extract(obj, arr, key)
return values
CodePudding user response:
You can use this code to acheive the same (not optimized though).
import json
# Opening JSON file
f = open('del.json')
data = json.load(f)
arr = []
def json_extract(obj, key):
def dfs(obj, key, prefix):
for k, v in obj.items():
if(isinstance(v, dict)):
if(k == key):
arr.append((prefix "." k if prefix else k, v))
else:
dfs(v, key, prefix "." k if prefix else k)
elif(isinstance(v, list)):
if(k == key):
arr.append((prefix "." k if prefix else k, v))
else:
for i, val in enumerate(v):
dfs(val, key, prefix k f"[{i}]")
dfs(obj, key, "")
json_extract(data, "id")
for i in arr:
print(i)
CodePudding user response:
Thanks for providing solution Olvin Right.
def get_paths(source, key="", target = None):
if isinstance(source, dict):
for source_key, source_value in source.items():
tmp_key = f"{key}.{source_key}" if key else source_key
if source_key == target:
yield tmp_key, source_value, source.get('_type')
else:
yield from get_paths(source_value, tmp_key, target)
elif isinstance(source, (list, tuple, set, frozenset)):
for index, value in enumerate(source):
yield from get_paths(value, f"{key}[{index}]", target)