I have a .json file which has a similar structure like this:
{
"cars": [
{
"FIAT": [
{"model_id": 153},
{"model_id": 194}
]
},
{
"AUDI": [
{"model_id": 261}
]
},
{
"BMW": [
{"model_id": 264}
]
}
]
}
My end goal is to retrieve the following:
{"model_id": 153},
{"model_id": 194},
{"model_id": 261},
{"model_id": 264}
Currently my code which gets me this result is this:
for cars in dir['cars']:
for brand in cars:
for model in cars[brand]:
print(model)
My question is that do we have a better way to access these details? I know that itertools.product is used to replace nested for loops, but can it be applied in this scenario?
CodePudding user response:
I think this is exactly the problem that ijson tries to solve, loading partial information from a json file.
CodePudding user response:
product
isn't useful here, as you don't have two independent lists to compute a product from. (Nor do you actually want a product of anything). You can, however, use a list comprehension with multiple iterators
[x for c in d['cars'] for v in c.values() for x in v]
one of which can be replaced with itertools.chain
operating on a generator expression:
list(chain.from_iterable(v for c in d['cars'] for v in c.values()))
You can apply chain.from_iterable
again:
list(chain.from_iterable(chain.from_iterable(c.values() for c in d['cars'])))
though readability may start to suffer.
A final version that does away with all explicit iteration
from itertools import chain
from functools import methodcaller
list(chain.from_iterable(
chain.from_iterable(
map(methodcaller('values'), d['cars'])))
is only for the most extreme adherents to functional programming and higher-order functions :)
CodePudding user response:
You can use jq to process the json and extract what you want. Here is an example for your data https://jqplay.org/s/mIaelGNpXO