Объединение списка словарей
Помогите пожалуйста с ситуацией. Получаю два ответа в формате JSON.
eventList =
[
{'id': '1', 'name': 'someName1'},
{'id': '2', 'name': 'someName2'},
{'id': '3', 'name': 'someName2'}
]
statistic =
[
{'id': '1', 'members': '428'},
{'id': '2', 'members': '117'}
]
Надо их объединить:
result =
[
{'id': '1', 'name': 'someName1', 'members': '428'},
{'id': '2', 'name': 'someName2', 'members': '117'},
{'id': '3', 'name': 'someName2'}
]
Опыта не так много и сам смогу реализовать лишь топорно.
Ответы (3 шт):
Автор решения: Zhihar
→ Ссылка
Я бы сделал так:
eventList = [
{'id': '1', 'name': 'someName1'},
{'id': '2', 'name': 'someName2'},
{'id': '3', 'name': 'someName2'}
]
statistic = [
{'id': '1', 'members': '428'},
{'id': '2', 'members': '117'}
]
dict1 = dict((obj['id'], obj) for obj in eventList)
dict2 = dict((obj['id'], obj) for obj in statistic)
res = [dict1.get(key, dict()) | dict2.get(key, dict()) for key in set(list(dict1.keys()) + list(dict2.keys()))]
print(res)
можно и покороче сделать вариант:
res = [dict1.get(key, dict()) | dict2.get(key, dict()) for key in (dict1 | dict2).keys()]
правда более ресурсоемко будет ибо идет объединение словарей, хотя достаточно лишь получить совокупность ключей двух словарей (как в первом примере)
Автор решения: ganz
→ Ссылка
Костыли для более ранних версий питона
def implict(main, other):
'''
update list of dict recursive, using 'id' as key
>>>implict([{'id':'1','n':'A'},{'id':'2','n':'B'}],[{'id':'3','n':'C'},{'id':'1','n':'NOT A'},{'id':'2','not n':'not n'}])
[{'id': '2', 'n': 'B'}, {'id': '1', 'n': 'A'}, {'id': '2', 'not n': 'not n', 'n': 'B'}]
'''
res=[]
for elementA in other:
for elementB in main:
if elementA['id']==elementB['id']:
subres={}
subres.update(elementA)
subres.update(elementB)
res.append(subres)
elementA=subres #fix
if elementA not in res:
res.append(elementB)
print(res)
return(res)
Автор решения: SergFSM
→ Ссылка
еще одно решение через промежуточный словарь:
from itertools import chain
res_dict = {}
for d in chain(eventList, statistic):
res_dict.setdefault(d['id'], {}).update(d)
res_list = list(res_dict.values())
результат:
print(res_list)
'''
[{'id': '1', 'name': 'someName1', 'members': '428'},
{'id': '2', 'name': 'someName2', 'members': '117'},
{'id': '3', 'name': 'someName2'}]
'''
UPD
В комментариях было предложение решить с помощью pandas. У меня получилось как-то так:
import pandas as pd
res = pd.DataFrame(eventList).merge(pd.DataFrame(statistic),
how='outer').fillna('0').to_dict('records')
результат такой:
[{'id': '1', 'name': 'someName1', 'members': '428'},
{'id': '2', 'name': 'someName2', 'members': '117'},
{'id': '3', 'name': 'someName2', 'members': '0'}]