Pythonic способ перебора через файл json

#python #json #for-loop #itertools

#python #json #for-цикл #itertools

Вопрос:

У меня есть файл .json, который имеет аналогичную структуру, например:

 {
  "cars": [
    {
    "FIAT": [
      {"model_id": 153},
      {"model_id": 194}
    ]
    },
    {
    "AUDI": [
      {"model_id": 261}
    ]
    },
    {
    "BMW": [
      {"model_id": 264}
    ]
    }
  ]
}
 

Моя конечная цель — получить следующее:

       {"model_id": 153},
      {"model_id": 194},
      {"model_id": 261},
      {"model_id": 264}

 

В настоящее время мой код, который дает мне этот результат, таков:

     for cars in dir['cars']:
        for brand in cars:
            for model in cars[brand]:
                print(model)
 

Мой вопрос в том, есть ли у нас лучший способ доступа к этим деталям? Я знаю, что itertools.product используется для замены вложенных циклов for , но может ли он быть применен в этом сценарии?

Комментарии:

1. Лучший способ в отношении каких критериев?

2. @DaniMesejo может быть, более pythonic способ или лучшая производительность

Ответ №1:

Я думаю, что это именно та проблема, которую пытается решить ijson, загружая частичную информацию из файла json.

Ответ №2:

product здесь бесполезно, поскольку у вас нет двух независимых списков для вычисления продукта. (И вам на самом деле не нужен продукт чего-либо). Однако вы можете использовать понимание списка с несколькими итераторами

 [x for c in d['cars'] for v in c.values() for x in v]
 

один из которых может быть заменен на itertools.chain работу с выражением генератора:

 list(chain.from_iterable(v for c in d['cars'] for v in c.values()))
 

Вы можете подать chain.from_iterable заявку снова:

 list(chain.from_iterable(chain.from_iterable(c.values() for c in d['cars'])))
 

хотя читаемость может начать страдать.


Окончательная версия, которая устраняет все явные итерации

 from itertools import chain
from functools import methodcaller

list(chain.from_iterable(
       chain.from_iterable(
        map(methodcaller('values'), d['cars'])))
 

предназначен только для самых крайних приверженцев функционального программирования и функций более высокого порядка 🙂

Ответ №3:

Вы можете использовать jq для обработки json и извлечения того, что вы хотите. Вот пример для ваших данных https://jqplay.org/s/mIaelGNpXO