Сложите значения одного и того же ключа во вложенный словарь - PullRequest
0 голосов
/ 15 января 2020

Я пытаюсь подсчитать общие значения для словарей с одинаковыми подключами. У меня есть список, содержащий соответствующие ключи mylist, мне нужно только подсчитать сумму значений для каждого элемента в списке.

mylist = ['age','answ1', 'answ2', 'answ3']
d = {'01': {'age':19, 'answ1':3, 'answ2':7, 'answ3':2}, '02': {'age':52, 'answ1':8, 'answ2':1, 'answ3':10},...}

Я пробовал

tot = []
for k,v in d.items():
    for ke, va in v.items():
        for i in mylist[0:]
            count=0
            if ke == i:
                count+=v[ke]
                tot.append(count)

, но вместо суммы значений с одним и тем же ключом я получаю значения разных ключей в порядке появления в словаре. Ожидаемый результат будет

tot = [71, 11, 8, 12]

Что я получу

tot = [19, 3, 7, 2, 52, 8, 1, 10]

Ответы [ 6 ]

4 голосов
/ 15 января 2020

С collections.Counter:

>>> ctr = sum(map(Counter, d.values()), Counter())
>>> [ctr[x] for x in mylist]
[71, 11, 8, 12]

Или:

>>> [sum(e[k] for e in d.values()) for k in mylist]
[71, 11, 8, 12]

В случае, если в некоторых поддиктах могут отсутствовать ключи, просто используйте e.get(k, 0). Решению Counter оно не нужно, оно по умолчанию предоставляет нули.

Хмм, поскольку вы теперь приняли решение результата dict ...

>>> dict(sum(map(Counter, d.values()), Counter()))
{'age': 71, 'answ1': 11, 'answ2': 8, 'answ3': 12}

Или, может быть, просто

>>> sum(map(Counter, d.values()), Counter())
Counter({'age': 71, 'answ3': 12, 'answ1': 11, 'answ2': 8})

Хотя у них может быть больше ключей, чем просто нужных, если в ваших данных их больше.

1 голос
/ 15 января 2020

Если вы хотите sh сохранить свой результат в словаре, вы можете создать его с помощью ключей из вашего списка и рассчитать там результаты.

result = {i: 0 for i in mylist}

for k, v in d.items():
    result['age'] += v['age']
    result['answ1'] += v['answ1']
    result['answ2'] += v['answ2']
    result['answ3'] += v['answ3']

result
{'age': 71, 'answ1': 11, 'answ2': 8, 'answ3': 12}

Однако это не зависит от ключей меняется, порядок не должен иметь значения.

РЕДАКТИРОВАТЬ

Вы можете сделать это независимо от имен ключей с помощью следующего обновления. Обратите внимание, что это добавляет одну дополнительную итерацию.

result = {i: 0 for i in mylist}
for k, v in d.items():
    for ke, va in v.items():
        result[ke] += v[ke]
0 голосов
/ 15 января 2020

То же самое, но другое.

>>> import operator
>>> f = operator.itemgetter(*mylist)
>>> vals = map(f,d.values())
>>> sums = map(sum,zip(*vals))
>>> result = dict(zip(mylist,sums))
>>> result
{'age': 71, 'answ1': 11, 'answ2': 8, 'answ3': 12}

Если вы не хотите диктовать, пропустите это и используйте result = list(sums)

0 голосов
/ 15 января 2020

Вы можете выполнить sh, используя списочные выражения, zip и map. Во-первых, мы хотим извлечь соответствующие значения из каждого поддикта:

>>> vals = [[v[k] for k in mylist] for v in d.values()]
>>> vals
[[19, 3, 7, 2], [52, 8, 1, 10]]

Теперь мы хотим выполнить поэлементную сумму для всех подсписков:

>>> result = map(sum, zip(*vals))
>>> list(result)
[71, 11, 8, 12]

Помещение всего в одну строку:

>>> result = map(sum, zip(*([v[k] for k in mylist] for v in d.values())))
>>> list(result)
[71, 11, 8, 12]

Преимущество этого подхода состоит в том, что мы получаем доступ только к тем ключам, которые мы хотим построить, вместо создания полного Counter, а затем извлекаем данные.

0 голосов
/ 15 января 2020

Попробуйте следующий код

for i in mylist:
count=0
for k,v in d.items():
    for ke, va in v.items():
        if ke == i:
            count+=va
tot.append(count)

~

0 голосов
/ 15 января 2020
mylist = ['age','answ1', 'answ2', 'answ3']
d = {'01': {'age':19, 'answ1':3, 'answ2':7, 'answ3':2}, '02': {'age':52, 'answ1':8, 'answ2':1, 'answ3':10}}

tot = [0] * len(mylist)
for k in d:
    for idx, i in enumerate(mylist):
        tot[idx] += d[k].get(i, 0)

print(tot)

Отпечатки:

[71, 11, 8, 12]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...