Python анализировать и выравнивать только некоторые поля в списке - PullRequest
1 голос
/ 19 февраля 2020

У меня есть JSON, который я преобразовал в список python диктов, который выглядит следующим образом:

[
{'id': 8675309,
 'slug': 'name',
 'campaigns': [
   {
   'part_id': 'sfgsdfgsd',
   'client_id': '1sdfgsdfg',
   'business_id': None,
   'metadata': {'field':1}},
   {
   'part_id': '354yyr',
   'client_id': 'erty465',
   'business_id': None,
   'metadata': {'field':10}
   }
   ]
},
{'id': 1234567,
 'slug': 'name2',
 'campaigns': [
   {
   'part_id': 'wertyw',
   'client_id': 'sighs',
   'business_id': None,
   'metadata': {'field':1}}
   ]
}

, и мне в основном нужно сгладить part_id, client_id, и business_id из списка campaigns при сохранении полей id и slug. В основном я ищу результат, который выглядит следующим образом:

[
    {
     'id': 8675309,
     'slug': 'name',
     'part_id': 'sfgsdfgsd',
     'client_id': '1sdfgsdfg',
     'business_id': None,
    },
    {
     'id': 8675309,
     'slug': 'name',
     'part_id': '354yyr',
     'client_id': 'erty465',
     'business_id': None,
    },
    {
     'id': 1234567,
     'slug': 'name2',
     'part_id': 'wertyw',
     'client_id': 'sighs',
     'business_id': None,
    }
]

Я знаю, как сгладить данные кампании следующим образом:

campaigns = [i['campaigns'] for i in data]
campaigns = [item for sublist in campaigns for item in sublist]

, где data - это список диктует, но как мне это сделать, поддерживая поля id и slug?

Ответы [ 2 ]

2 голосов
/ 19 февраля 2020

Вы можете использовать operator.itemgetter(), чтобы получить определенные ключи из словаря в одном выражении. Затем используйте zip() для создания пар ключ-значение и передайте их в dict().

Код :

from operator import itemgetter

source = [] # YOUR SOURCE

main_fields = 'id', 'slug'
sub_fields = 'part_id', 'client_id', 'business_id'
main_getter = itemgetter(*main_fields)
sub_getter = itemgetter(*sub_fields)
result = []

for item in source:
    parsed = main_getter(item)
    for campaign in item['campaigns']:
        result.append(dict(zip(main_fields + sub_fields, parsed + sub_getter(campaign))))

Вы также можете использовать понимание вложенного списка :

result = [dict(zip(main_fields + sub_fields, itemgetter(*main_fields)(item) + itemgetter(*sub_fields)(campaign))) for item in source for campaign in item['campaigns']]
2 голосов
/ 19 февраля 2020

Дайте это попробовать. Хитрость заключается в том, чтобы создать базовый диктат для слияния с данными вашей кампании.

def squash(data):
    results = []
    for item in data:
        base = {
          'id': item['id'],
          'slug': item['slug']
        }
        for campaign in item.get('campaigns', []):
            results.append({
                **base,
                'part_id': campaign['part_id'],
                'business_id': campaign['business_id'],
                'client_id': campaign['client_id']
            })
    return results
...