Пересечение двух списков словарей по ключу - PullRequest
0 голосов
/ 21 декабря 2018

У меня есть два разных списка словарей,

list1 = [{'count': 351, 'att_value': 'one'},
         {'count': 332,  'att_value': 'two'},
         {'count': 336,  'att_value': 'six'},
         {'count': 359,  'att_value': 'nine'},
         {'count': 304,  'att_value': 'four'}]

list2 = [{'count': 359,'person_id' : 4},
         {'count': 351, 'person_id' : 12},
         {'count': 381, 'person_id' : 8}]

Как найти пересечение list_A с list_B на основе ключа «count», включая оставшуюся часть ключа как list_C?

list3 = [{'count':359, 'att_value' : 'nine', 'person_id':4},
         {'count':351, 'att_value' : 'one', 'person_id':12},
         {'count':381, 'att_value' : '-', 'person_id':8}] 

Я бы хотел сохранить ключи из list2, но с отсутствующими значениями из list1, представленными знаком "-".

Ответы [ 4 ]

0 голосов
/ 21 декабря 2018

Более подробный цикл for обновляет объекты list2:

for item2 in list2:
  item2['att_value'] = '-'
  item1 = [ item1 for item1 in list1 if item1['count'] == item2['count'] ]
  if item1: item2.update(item1[0])

print(list2)
#=> [{'count': 359, 'person_id': 4, 'att_value': 'nine'}, {'count': 351, 'person_id': 12, 'att_value': 'one'}, {'count': 381, 'person_id': 8, 'att_value': '-'}]
0 голосов
/ 21 декабря 2018

Для этого вы также можете использовать библиотеку панд :

In [102]: df1 = pd.DataFrame(list1)
In [104]: df2 = pd.DataFrame(list2)

In [106]: pd.merge(df2,df1, on='count', how='left').fillna('-')
Out[106]: 
     count att_value
0    359      nine
1    351       one
2    381         -
0 голосов
/ 21 декабря 2018

Предполагая, что словари в list1 используют одни и те же ключи и что у вас есть Python 3.5 или новее, вы можете написать следующее понимание списка.

>>> count2dict = {d['count']:d for d in list1}                                                                                                                  
>>> dummies = dict.fromkeys(list1[0], '-')                                                                                                                      
>>> [{**count2dict.get(d['count'], dummies), **d} for d in list2]                                                                                              
[{'count': 359, 'att_value': 'nine', 'person_id': 4},
 {'count': 351, 'att_value': 'one', 'person_id': 12},
 {'count': 381, 'att_value': '-', 'person_id': 8}]
0 голосов
/ 21 декабря 2018

Вы можете сделать это с пониманием списка.Сначала создайте набор всех отсчетов из list2, а затем отфильтруйте словари на основе проверки членства в наборе с постоянным временем.

counts = {d2['count'] for d2 in list2}
list3 = [d for d in list1 if d['count'] in counts]

print(list3)
# [{'count': 351, 'att_value': 'one', 'person_id': 12}, 
#  {'count': 359, 'att_value': 'nine', 'person_id': 4}]

(Re: Edit) Для обработки других ключей (кроме просто"att_value") соответственно, задав значение по умолчанию '-' таким же образом, вы можете использовать:

keys = list1[0].keys() - {'count'}
idx = {d['count'] : d for d in list1}
list3 = []
for d in list2:
    d2 = idx.get(d['count'], dict.fromkeys(keys, '-'))
    d2.update(d)
    list3.append(d2)

print(list3)
# [{'count': 359, 'att_value': 'nine', 'person_id': 4},
#  {'count': 351, 'att_value': 'one', 'person_id': 12},
#  {'person_id': 8, 'att_value': '-', 'count': 381}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...