I have a json file like this:
{
"results": [
{
"rule": {
"description": "a",
"engine": "b",
"id": 0,
"name": "name",
"test_requires": "all",
}
}
{
"rule": {
"description": "a",
"engine": "b",
"id": 1,
"name": "name",
"test_requires": "one",
}
}
{
"rule": {
"description": "a",
"engine": "b",
"id": 2,
"name": "main",
"test_requires": "one",
}
}
]
}
So i want to iterate through this file and get several key values from every nested dict which are also nested to a list
something like :
result = []
reuslt2 = []
templates = json.load(jsonfile)
for item in templates[results][0]:
result.append(templates[results][0][id]
result2.append(templates[results[0][name]
Obviously this doesn't work cause it only loops from the first nested dict with id:0
How can i make a successful loop into this nested dict - list going all the way through to work in python ?
Thank you.
CodePudding user response:
i think what you meant (correctly formatted of json file)-
{
"results": [
{
"rule": {
"description": "a",
"engine": "b",
"id": 0,
"name": "name",
"test_requires": "all"
}
},
{
"rule": {
"description": "a",
"engine": "b",
"id": 1,
"name": "name",
"test_requires": "one"
}
},
{
"rule": {
"description": "a",
"engine": "b",
"id": 2,
"name": "main",
"test_requires": "one"
}
}
]
}
as your json file
and this is what you want-
import json
result = []
result2 = []
with open('./records.json') as f:
templates = json.load(f)
for item in templates["results"]:
result.append(item["rule"]["id"])
result2.append(item["rule"]["name"])
print(result)
print(result2)
CodePudding user response:
If you don't know beforehand on what level id
and name
might be, you'll have to use a recursion:
templates = {
"results": [
{
"rule": {
"description": "a",
"engine": "b",
"id": 0,
"name": "name",
"test_requires": "all",
}
},
{
"rule": {
"description": "a",
"engine": "b",
"id": 1,
"name": "name",
"test_requires": "one",
}
},
{
"rule": {
"description": "a",
"engine": "b",
"id": 2,
"name": "main",
"test_requires": "one",
}
}
]
}
ids = []
names = []
def get_ids_and_names(templ):
if isinstance(templ, dict):
if 'id' in templ:
ids.append(templ['id'])
if 'name' in templ:
names.append(templ['name'])
for val in templ.values():
get_ids_and_names(val)
elif isinstance(templ, list):
for elt in templ:
get_ids_and_names(elt)
get_ids_and_names(templates)
print(ids)
print(names)
Output:
[0, 1, 2]
['name', 'name', 'main']
CodePudding user response:
You could pack the id
and name
values from each record in templates["results"]
into tuples, zip
them, and then unpack it into the results:
result, result2 = zip(*((rec["rule"]["id"], rec["rule"]["name"]) for rec in templates["results"]))
Result:
(0, 1, 2), ('name', 'name', 'main')
If you want lists instead:
result, result2 = map(
list,
zip(*((rec["rule"]["id"], rec["rule"]["name"]) for rec in templates["results"]))
)
Result:
[0, 1, 2], ['name', 'name', 'main']