итоговый список значений словаря - PullRequest
0 голосов
/ 10 июня 2018

У меня есть список словаря в этой форме:

[
{'signal_8': 1, 'signal_1': 7, 'signal_10': 5, 'signal_5': 2, 'signal_2': 5, 'signal_6': 3, 'signal_4': 9, 'signal_3': 6, 'signal_9': 4, 'signal_7': 8}, 

{'signal_8': 1, 'signal_1': 7, 'signal_10': 5, 'signal_5': 2, 'signal_2': 5, 'signal_6': 3, 'signal_4': 9, 'signal_3': 6, 'signal_9': 4, 'signal_7': 8},

{'signal_8': 1, 'signal_1': 7, 'signal_10': 5, 'signal_5': 2, 'signal_2': 5, 'signal_6': 3, 'signal_4': 9, 'signal_3': 6, 'signal_9': 4, 'signal_7': 8},
]

, и я хочу суммировать значения в этом ключе для каждого элемента в списке следующим образом:

    {
     'signal_8': 3,
     'signal_1': 21,
     'signal_10': 15,
     'signal_5': 6,
     'signal_2': 15,
     'signal_6': 9,
     'signal_4': 27,
     'signal_3': 18,
     'signal_9': 12,
     'signal_7': 24
    }

я попробовал следующее:

    result = {}
    sm = 0
    for elm in original_list:
        for k,v in elm.items():
            sm += v
            result[k] = sm
    print(result)

, но все равно не работает.

Ответы [ 7 ]

0 голосов
/ 10 июня 2018

Можете ли вы попробовать ниже код

basedict=siglist[0]
for k in basedict.keys():
    result=[currdict[k] for currdict in siglist]
    endval=sum(result)
    print("Key %s and sum of values %d"%(k,endval))

Вывод

Key signal_9 and sum of values 12
Key signal_2 and sum of values 15
Key signal_8 and sum of values 3
Key signal_5 and sum of values 6
Key signal_7 and sum of values 24
Key signal_10 and sum of values 15
Key signal_1 and sum of values 21
Key signal_6 and sum of values 9
Key signal_4 and sum of values 27
Key signal_3 and sum of values 18

Примечание: - Поскольку мы уверены, что все ключи во всех словарях одинаковы, это решение работает хорошо.Если у вас есть словарь с несоответствующими элементами, это приведет к KeyError.Так что знайте об этом ограничении

0 голосов
/ 10 июня 2018

Подобно ответу daveruinseverything, я решил бы это с помощью Counter, но использовал бы его update метод.

Пусть signals будет вашим списком диктов.

>>> from collections import Counter
>>> c = Counter()
>>> for d in signals:
...     c.update(d)
... 
>>> c
Counter({'signal_4': 27, 'signal_7': 24, 'signal_1': 21, 'signal_3': 18, 'signal_10': 15, 'signal_2': 15, 'signal_9': 12, 'signal_6': 9, 'signal_5': 6, 'signal_8': 3})

Ради оп, не могли бы вы кратко описать, что здесь происходит?

A Counter работает аналогично dict, но его метод update добавляет значения кзначения существующих ключей вместо их переопределения.

0 голосов
/ 10 июня 2018

Ваш текущий код использует одну суммирующую сумму для всех сигналов, когда вместо этого вам нужна отдельная сумма для каждого сигнала.

Если вы хотите, чтобы ваш оригинальный код работал, вам нужно сначала проверить, существует ли ключ в result, и инициализировать его 0 заранее, если это не так.Затем накапливайте сумму для соответствующего ключа.

Код:

result = {}
for elm in original_list:
    for k, v in elm.items():

        # Initialise it if it doesn't exist
        if k not in result:
            result[k] = 0

        # accumulate sum seperately 
        result[k] += v

print(result)

Выход:

{'signal_9': 12, 'signal_8': 3, 'signal_1': 21, 'signal_3': 18, 'signal_2': 15, 'signal_5': 6, 'signal_4': 27, 'signal_7': 24, 'signal_6': 9, 'signal_10': 15}

Примечание: Как и другиепоказали, что во избежание инициализации вы можете использовать collections.defaultdict() или collections.Counter().

0 голосов
/ 10 июня 2018

Проблема с вашим кодом в том, что вы суммируете sm и v независимо от ключа.Ниже вы можете найти переформатированную версию вашего кода, которая работает.Он просто добавляет значения из каждого элемента из списка в результирующий объект:

from collections import defaultdict

result = defaultdict(int)

for elm in original_list:
    for k, v in elm.items():
        result[k] += v
print(result)

Или с одним вкладышем вы можете иметь:

result = {key: sum(e[key] for e in original_list) for key in original_list[0].keys()}
0 голосов
/ 10 июня 2018

С itertools.groupby вы можете сделать что-то вроде

merged_list = sorted(p for l in original_list for p in l.items())
groups = groupby(merged_list, key=lambda p: p[0])
result = {signal: sum(pair[1] for pair in pairs) for signal, pairs in groups}

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

{k: sum(d[k] for d in original_list) for k in original_list[0]}

Также обратите внимание, что библиотека анализа данных pandas делает такие операции тривиальными:

In [70]: import pandas as pd

In [72]: pd.DataFrame(original_list).sum()
Out[72]:
signal_1     21
signal_10    15
signal_2     15
signal_3     18
signal_4     27
signal_5      6
signal_6      9
signal_7     24
signal_8      3
signal_9     12
dtype: int64
0 голосов
/ 10 июня 2018

То, что вы хотите, это тип коллекции Counter.Документы Python по коллекциям описывают это лучше всего, но по сути Counter - это особый вид словаря, в котором все значения являются целыми числами.Вы можете передать любой ключ, включая несуществующие, и добавить к ним.Например:

from collections import Counter

original_list = [
    {'signal_8': 1, 'signal_1': 7, 'signal_10': 5, 'signal_5': 2, 'signal_2': 5, 'signal_6': 3, 'signal_4': 9, 'signal_3': 6, 'signal_9': 4, 'signal_7': 8}, 
    {'signal_8': 1, 'signal_1': 7, 'signal_10': 5, 'signal_5': 2, 'signal_2': 5, 'signal_6': 3, 'signal_4': 9, 'signal_3': 6, 'signal_9': 4, 'signal_7': 8},
    {'signal_8': 1, 'signal_1': 7, 'signal_10': 5, 'signal_5': 2, 'signal_2': 5, 'signal_6': 3, 'signal_4': 9, 'signal_3': 6, 'signal_9': 4, 'signal_7': 8},
]

result = Counter()

for elem in original_list:
    for key, value in elem.items():
        result[key] += value

print(result)

Редактировать: @timgeb предоставляет вариант ответа, который использует метод update() для объектов Counter.Я бы рекомендовал это как лучший ответ здесь

0 голосов
/ 10 июня 2018

Попробуйте:

original_list = [
{'signal_8': 1, 'signal_1': 7, 'signal_10': 5, 'signal_5': 2, 'signal_2': 5, 'signal_6': 3, 'signal_4': 9, 'signal_3': 6, 'signal_9': 4, 'signal_7': 8}, 

{'signal_8': 1, 'signal_1': 7, 'signal_10': 5, 'signal_5': 2, 'signal_2': 5, 'signal_6': 3, 'signal_4': 9, 'signal_3': 6, 'signal_9': 4, 'signal_7': 8},

{'signal_8': 1, 'signal_1': 7, 'signal_10': 5, 'signal_5': 2, 'signal_2': 5, 'signal_6': 3, 'signal_4': 9, 'signal_3': 6, 'signal_9': 4, 'signal_7': 8},
]
print({k:sum([x[k] for x in original_list if k in x]) for i in original_list for k,v in i.items()})

Вывод:

{'signal_8': 3, 'signal_1': 21, 'signal_10': 15, 'signal_5': 6, 'signal_2': 15, 'signal_6': 9, 'signal_4': 27, 'signal_3': 18, 'signal_9': 12, 'signal_7': 24}

Обратите внимание, что если пропущены сигналы, он просто будет считать его нулевым

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