Перебрать список словарей и найти соответствующие элементы из списка и добавить значение соответствующего ключа к defaultdict

У меня есть список словарей. Назовем его: list_of_dict. Словари в списке имеют вид:

{'a' : 1,
'b' : 5,
'c' : 3,
'd' : 6}

и

{'a' : 3,
'f' : 2,
'g' : 1,
'h' : 3,
'i' : 5,
'j' : 3}

У меня есть еще один список под названием list_to_match, который содержит только несколько букв: ['a', 'f', 'x']

Мне нужно перебрать list_of_dict и найти ключи, соответствующие элементу в списке, и добавить значения в пустой defaultdict элементов списка. Если не найдено, добавьте 0 к списку.

defaultdict инициализируется как:

d = collections.defaultdict(list)

Я хочу, чтобы возможный defaultdict выглядел так:

{'a' : [1, 3],
'f' : [0, 2],
'x' : [0, 0]}

Пока что у меня есть:

for ld in list_of_dict:
    for match in list_to_match:
        for k, v in ld.items():
            d[match].append(v)
    d[match].append(0)

Теперь все это работает, кроме последней строки, потому что, очевидно, совпадения в этой области не существует. Теперь все, что я получаю в defaultdict, это:

{'a' : [1, 3],
'f' : [2]}

0 отсутствует, как и x. Как это исправить?


person panaceanoob    schedule 24.10.2018    source источник
comment
Итак, 0 означает не найдено?   -  person Dani Mesejo    schedule 24.10.2018
comment
правильно, но лучше добавить 0, чем None или что-то в этом роде.   -  person panaceanoob    schedule 24.10.2018
comment
Значение «f» равно 2 в словаре, но 5 на выходе, это правильно?   -  person Dani Mesejo    schedule 24.10.2018
comment
нет, мой плохой. исправить это.   -  person panaceanoob    schedule 24.10.2018
comment
что такое коллекции?   -  person Riley Hughes    schedule 24.10.2018
comment
Коллекции @RileyHughes — это тип данных Python. docs.python.org/3/library/collections.html   -  person panaceanoob    schedule 24.10.2018


Ответы (3)


Вы можете сделать это, не нужно использовать defaultdict:

list_of_dict = [{'a': 1, 'b': 5,
                 'c': 3,
                 'd': 6}, {'a': 3,
                           'f': 2,
                           'g': 1,
                           'h': 3,
                           'i': 5,
                           'j': 3}]

list_to_match = ['a', 'f', 'x']

d = {}
for match in list_to_match:
    for ld in list_of_dict:
        d.setdefault(match, []).append(ld.get(match, 0))

print(d)

Вывод

{'a': [1, 3], 'x': [0, 0], 'f': [0, 2]}
person Dani Mesejo    schedule 24.10.2018
comment
Это очень элегантно. Спасибо! - person panaceanoob; 24.10.2018

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

{i: [j[i] if i in j else 0 for j in list_of_dict] for i in list_to_match}

Урожайность:

{'a': [1, 3], 'f': [0, 2], 'x': [0, 0]}

Еще проще:

{i: [j.get(i, 0) for j in list_of_dict] for i in list_to_match}
person rahlf23    schedule 24.10.2018
comment
j[i] if i in j else 0 то же самое, что и j.get(i, 0), что, на мой взгляд, более читабельно. - person Håken Lid; 24.10.2018

IIUC, вы можете просто сделать:

for m in list_to_match:
    d[m] = [ld.get(m, 0) for ld in list_of_dict]
print(d)
#defaultdict(list, {'a': [1, 3], 'f': [0, 2], 'x': [0, 0]})

Это также сработает для обычного словаря, если вы не хотите использовать defaultdict.

person pault    schedule 24.10.2018