Python: сопоставьте два списка словарей по ключу и объедините совпадающие дикты

#python #list #dictionary #merge #intersection

#python #Список #словарь #объединить #пересечение

Вопрос:

Имея два списка словарей, таких как

 big = [{'id': 1234, 'name': 'ipod'}, {'id': 1235, 'name': 'ipod x'}, {'id': 1236, 'name': 'ipod touch'}]

small = [{'id': 1236, 'url': 'directUrl1'}, {'id': 1235, 'url': 'directUrl2'}]
  

Я хотел бы реализовать эффективный и питонический способ поиска пересечений между двумя списками (на основе id ) и создания нового списка объединенных dicts:

 res = [{'id': 1236, 'url': 'directUrl1', 'name': 'ipod touch'}, {'id': 1235, 'url': 'directUrl2', 'name': 'ipod x'}]
  

Мой текущий подход:

 >>> res = []
>>>
>>> for item in [x for x in small if x['id'] in [y['id'] for y in big]]:
...  res.append({**item, **[x for x in big if x['id'] == item['id']][0]})
...
>>> res
[{'id': 1236, 'url': 'directUrl1', 'name': 'ipod touch'}, {'id': 1235, 'url': 'directUrl2', 'name': 'ipod x'}]
  

Ответ №1:

Pythonic не означает плотный 😉

Как насчет:

 new_dictlist = []
for d1 in small:
    for d2 in big:
        if d1['id'] == d2['id']:
            new_dictlist.append({'id':d1['id'], 'url':d1['url'], 'name':d2['name']})
  

Или однострочный:

 [{**x, **y} for x in big for y in small if x['id'] == y['id']]
  

Ответ №2:

Вы можете создать сопоставление для big этих карт id с name помощью . После этого вы можете выполнить итерацию по small списку и создать новый список словарей.

 >>> big_map = {d['id']:d['name'] for d in big}
>>> res = [{'id': d['id'], 'url':d['url'], 'name':big_map[d['id']]} for d in small if d['id'] in big_map]
>>> res
[{'id': 1236, 'url': 'directUrl1', 'name': 'ipod touch'}, {'id': 1235, 'url': 'directUrl2', 'name': 'ipod x'}]