Объединить список вложенных словарей - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть 3 списка, как показано ниже, которые извлекаются из файла PDF,

adID = ['9940542', '9940542', '10315065', '10315065', '11211744', '11211744', '11309685', '11309685', '12103490', '12103490', '12103490', '12103490', '12103490', '12103490', '12160150', '12160150']

description = ['Invalid Adjust(Platform Fee)', 'Invalid Adjust(Media Fee)', 'Invalid Adjust(Platform Fee)', 'Invalid Adjust(Media Fee)', 'Invalid Adjust(Platform Fee)', 'Invalid Adjust(Media Fee)', 'Invalid Adjust(Platform Fee)', 'Invalid Adjust(Media Fee)', 'Media Fee', 'Platform Fee', 'Invalid Adjust(Platform Fee)', 'TrueView Budget Adjust (Platofrm Fee)', 'Invalid Adjust(Media Fee)', 'TrueView Budget Adjust (Media Fee)', 'Media Fee', 'Platform Fee']

spendItem = ['-1.00', '-2.00', '-1.00', '-3.00', '-290.00', '-3403.00', '-57.00', '-670.00', '709472.00', '22703.00', '-30.00', '-301.00', '-348.00', '-9376.00', '549173.00', '17573.00']

И я преобразовал эти списки в список словарей, как показано ниже

total= [{'9940542': {'Invalid Adjust(Platform Fee)': '-1.00'}},
        {'9940542': {'Invalid Adjust(Media Fee)': '-2.00'}},
        {'10315065': {'Invalid Adjust(Platform Fee)': '-1.00'}},
        {'10315065': {'Invalid Adjust(Media Fee)': '-3.00'}},
        {'11211744': {'Invalid Adjust(Platform Fee)': '-290.00'}},
        {'11211744': {'Invalid Adjust(Media Fee)': '-3403.00'}},
        {'11309685': {'Invalid Adjust(Platform Fee)': '-57.00'}},
        {'11309685': {'Invalid Adjust(Media Fee)': '-670.00'}},
        {'12103490': {'Media Fee': '709472.00'}},
        {'12103490': {'Platform Fee': '22703.00'}},
        {'12103490': {'Invalid Adjust(Platform Fee)': '-30.00'}},
        {'12103490': {'TrueView Budget Adjust (Platofrm Fee)': '-301.00'}},
        {'12103490': {'Invalid Adjust(Media Fee)': '-348.00'}},
        {'12103490': {'TrueView Budget Adjust (Media Fee)': '-9376.00'}},
        {'12160150': {'Media Fee': '549173.00'}},
        {'12160150': {'Platform Fee': '17573.00'}}]

Есть ли способ перебрать этот список, чтобы объединить ключи и значения на основе adID. Например,

Expected_result= {'12103490': {'Invalid Adjust(Platform Fee)': '-30.00',TrueView Budget Adjust (Platofrm Fee)': '-301.00','Invalid Adjust(Media Fee)': '-348.00','TrueView Budget Adjust (Media Fee)': '-9376.00'}}

Или есть ли лучший способ объединить такие данные?

Ответы [ 4 ]

3 голосов
/ 18 февраля 2020

Использование dict.setdefault и простая итерация. Вы также можете использовать collection.defaultdict

Пример:

total= [{'9940542': {'Invalid Adjust(Platform Fee)': '-1.00'}},
        {'9940542': {'Invalid Adjust(Media Fee)': '-2.00'}},
        {'10315065': {'Invalid Adjust(Platform Fee)': '-1.00'}},
        {'10315065': {'Invalid Adjust(Media Fee)': '-3.00'}},
        {'11211744': {'Invalid Adjust(Platform Fee)': '-290.00'}},
        {'11211744': {'Invalid Adjust(Media Fee)': '-3403.00'}},
        {'11309685': {'Invalid Adjust(Platform Fee)': '-57.00'}},
        {'11309685': {'Invalid Adjust(Media Fee)': '-670.00'}},
        {'12103490': {'Media Fee': '709472.00'}},
        {'12103490': {'Platform Fee': '22703.00'}},
        {'12103490': {'Invalid Adjust(Platform Fee)': '-30.00'}},
        {'12103490': {'TrueView Budget Adjust (Platofrm Fee)': '-301.00'}},
        {'12103490': {'Invalid Adjust(Media Fee)': '-348.00'}},
        {'12103490': {'TrueView Budget Adjust (Media Fee)': '-9376.00'}},
        {'12160150': {'Media Fee': '549173.00'}},
        {'12160150': {'Platform Fee': '17573.00'}}]

rsult = {}
for i in total:
    for k, v in i.items():
        rsult.setdefault(k, {}).update(v)

print(rsult)

Выход:

{'10315065': {'Invalid Adjust(Media Fee)': '-3.00',
              'Invalid Adjust(Platform Fee)': '-1.00'},
 '11211744': {'Invalid Adjust(Media Fee)': '-3403.00',
              'Invalid Adjust(Platform Fee)': '-290.00'},
 '11309685': {'Invalid Adjust(Media Fee)': '-670.00',
              'Invalid Adjust(Platform Fee)': '-57.00'},
 '12103490': {'Invalid Adjust(Media Fee)': '-348.00',
              'Invalid Adjust(Platform Fee)': '-30.00',
              'Media Fee': '709472.00',
              'Platform Fee': '22703.00',
              'TrueView Budget Adjust (Media Fee)': '-9376.00',
              'TrueView Budget Adjust (Platofrm Fee)': '-301.00'},
 '12160150': {'Media Fee': '549173.00', 'Platform Fee': '17573.00'},
 '9940542': {'Invalid Adjust(Media Fee)': '-2.00',
             'Invalid Adjust(Platform Fee)': '-1.00'}}
1 голос
/ 18 февраля 2020

Вы можете сделать это с 1 строкой кода, используя python-benedict, это подкласс dict со многими функциями и это с открытым исходным кодом на GitHub .

Установка: pip install python-benedict

from benedict import benedict as bdict

data_input= [
    {'9940542': {'Invalid Adjust(Platform Fee)': '-1.00'}},
    {'9940542': {'Invalid Adjust(Media Fee)': '-2.00'}},
    {'10315065': {'Invalid Adjust(Platform Fee)': '-1.00'}},
    {'10315065': {'Invalid Adjust(Media Fee)': '-3.00'}},
    {'11211744': {'Invalid Adjust(Platform Fee)': '-290.00'}},
    {'11211744': {'Invalid Adjust(Media Fee)': '-3403.00'}},
    {'11309685': {'Invalid Adjust(Platform Fee)': '-57.00'}},
    {'11309685': {'Invalid Adjust(Media Fee)': '-670.00'}},
    {'12103490': {'Media Fee': '709472.00'}},
    {'12103490': {'Platform Fee': '22703.00'}},
    {'12103490': {'Invalid Adjust(Platform Fee)': '-30.00'}},
    {'12103490': {'TrueView Budget Adjust (Platofrm Fee)': '-301.00'}},
    {'12103490': {'Invalid Adjust(Media Fee)': '-348.00'}},
    {'12103490': {'TrueView Budget Adjust (Media Fee)': '-9376.00'}},
    {'12160150': {'Media Fee': '549173.00'}},
    {'12160150': {'Platform Fee': '17573.00'}}
]

data_output = bdict()
data_output.merge(*data_input)
print(data_output.dump())
1 голос
/ 18 февраля 2020

Вы можете попробовать это.

In [18]: for d in total:
    ...:     for k,v in d.items():
    ...:         if k not in new:
    ...:             new[k]=v
    ...:         else:
    ...:             new[k].update(v)

output

{'9940542': {'Invalid Adjust(Platform Fee)': '-1.00',
  'Invalid Adjust(Media Fee)': '-2.00'},
 '10315065': {'Invalid Adjust(Platform Fee)': '-1.00',
  'Invalid Adjust(Media Fee)': '-3.00'},
 '11211744': {'Invalid Adjust(Platform Fee)': '-290.00',
  'Invalid Adjust(Media Fee)': '-3403.00'},
 '11309685': {'Invalid Adjust(Platform Fee)': '-57.00',
  'Invalid Adjust(Media Fee)': '-670.00'},
 '12103490': {'Media Fee': '709472.00',
  'Platform Fee': '22703.00',
  'Invalid Adjust(Platform Fee)': '-30.00',
  'TrueView Budget Adjust (Platofrm Fee)': '-301.00',
  'Invalid Adjust(Media Fee)': '-348.00',
  'TrueView Budget Adjust (Media Fee)': '-9376.00'},
 '12160150': {'Media Fee': '549173.00', 'Platform Fee': '17573.00'}}
0 голосов
/ 09 марта 2020

Для записи, один вкладыш. Не использовать в рабочем коде (используйте setdefault, как в @ Rake sh answer) .

>>> adID = ['9940542', '9940542', '10315065', '10315065', '11211744', '11211744', '11309685', '11309685', '12103490', '12103490', '12103490', '12103490', '12103490', '12103490', '12160150', '12160150']
>>> description = ['Invalid Adjust(Platform Fee)', 'Invalid Adjust(Media Fee)', 'Invalid Adjust(Platform Fee)', 'Invalid Adjust(Media Fee)', 'Invalid Adjust(Platform Fee)', 'Invalid Adjust(Media Fee)', 'Invalid Adjust(Platform Fee)', 'Invalid Adjust(Media Fee)', 'Media Fee', 'Platform Fee', 'Invalid Adjust(Platform Fee)', 'TrueView Budget Adjust (Platofrm Fee)', 'Invalid Adjust(Media Fee)', 'TrueView Budget Adjust (Media Fee)', 'Media Fee', 'Platform Fee']
>>> spendItem = ['-1.00', '-2.00', '-1.00', '-3.00', '-290.00', '-3403.00', '-57.00', '-670.00', '709472.00', '22703.00', '-30.00', '-301.00', '-348.00', '-9376.00', '549173.00', '17573.00']

Вы можете легко вычислить total:

>>> total = [{k: {u: v}} for (k, u, v) in zip(adID, description, spendItem)]
>>> total
[{'9940542': {'Invalid Adjust(Platform Fee)': '-1.00'}}, {'9940542': {'Invalid Adjust(Media Fee)': '-2.00'}}, {'10315065': {'Invalid Adjust(Platform Fee)': '-1.00'}}, {'10315065': {'Invalid Adjust(Media Fee)': '-3.00'}}, {'11211744': {'Invalid Adjust(Platform Fee)': '-290.00'}}, {'11211744': {'Invalid Adjust(Media Fee)': '-3403.00'}}, {'11309685': {'Invalid Adjust(Platform Fee)': '-57.00'}}, {'11309685': {'Invalid Adjust(Media Fee)': '-670.00'}}, {'12103490': {'Media Fee': '709472.00'}}, {'12103490': {'Platform Fee': '22703.00'}}, {'12103490': {'Invalid Adjust(Platform Fee)': '-30.00'}}, {'12103490': {'TrueView Budget Adjust (Platofrm Fee)': '-301.00'}}, {'12103490': {'Invalid Adjust(Media Fee)': '-348.00'}}, {'12103490': {'TrueView Budget Adjust (Media Fee)': '-9376.00'}}, {'12160150': {'Media Fee': '549173.00'}}, {'12160150': {'Platform Fee': '17573.00'}}]

Объединенный список гораздо более громоздок:

>>> {k1: {u: v for d2 in total for k2, d2 in d2.items() for u, v in d2.items() if k2 == k1} for d1 in total for k1 in d1}
{'9940542': {'Invalid Adjust(Platform Fee)': '-1.00', 'Invalid Adjust(Media Fee)': '-2.00'}, '12103490': {'Media Fee': '709472.00', 'Platform Fee': '22703.00', 'Invalid Adjust(Platform Fee)': '-30.00', 'TrueView Budget Adjust (Platofrm Fee)': '-301.00', 'Invalid Adjust(Media Fee)': '-348.00', 'TrueView Budget Adjust (Media Fee)': '-9376.00'}, '12160150': {'Media Fee': '549173.00', 'Platform Fee': '17573.00'}, '10315065': {'Invalid Adjust(Platform Fee)': '-1.00', 'Invalid Adjust(Media Fee)': '-3.00'}, '11309685': {'Invalid Adjust(Platform Fee)': '-57.00', 'Invalid Adjust(Media Fee)': '-670.00'}, '11211744': {'Invalid Adjust(Platform Fee)': '-290.00', 'Invalid Adjust(Media Fee)': '-3403.00'}}

Это очень медленно, потому что вам нужно извлечь ключи, а затем найти элементы, соответствующие этим ключам.

Это проще написать, но не очень быстро, за один шаг:

>>> {k1: {u: v for (k2, u, v) in zip(adID, description, spendItem) if k2 == k1} for k1 in set(adID)}
{'9940542': {'Invalid Adjust(Platform Fee)': '-1.00', 'Invalid Adjust(Media Fee)': '-2.00'}, '12103490': {'Media Fee': '709472.00', 'Platform Fee': '22703.00', 'Invalid Adjust(Platform Fee)': '-30.00', 'TrueView Budget Adjust (Platofrm Fee)': '-301.00', 'Invalid Adjust(Media Fee)': '-348.00', 'TrueView Budget Adjust (Media Fee)': '-9376.00'}, '12160150': {'Media Fee': '549173.00', 'Platform Fee': '17573.00'}, '10315065': {'Invalid Adjust(Platform Fee)': '-1.00', 'Invalid Adjust(Media Fee)': '-3.00'}, '11309685': {'Invalid Adjust(Platform Fee)': '-57.00', 'Invalid Adjust(Media Fee)': '-670.00'}, '11211744': {'Invalid Adjust(Platform Fee)': '-290.00', 'Invalid Adjust(Media Fee)': '-3403.00'}}
...