字典值的总和列表

时间:2018-06-10 09:33:20

标签: python python-3.x list dictionary

我有一个这种形式的字典列表:

[
{'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},
]

并且我希望对列表中每个元素的this by key求和:

    {
     '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 :(得分:4)

与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})
  

为了Op,你能简单描述一下这里发生了什么吗?

Counter的工作方式类似于dict,但其update方法会将值添加到预先存在的键的值中,而不是覆盖它们。

答案 1 :(得分:3)

您想要的是Counter集合类型。 collections上的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方法。我建议将其作为最佳答案

答案 2 :(得分:3)

您的代码存在的问题是,无论密钥是什么,您都要汇总smv。您可以在下面找到适用于您的代码的重新格式化版本。它只是将列表中每个元素的值添加到结果对象中:

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()}

答案 3 :(得分:2)

使用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

答案 4 :(得分:1)

您当前的代码对所有信号使用一个累加和,而您需要为每个信号分别求和。

如果您希望原始代码有效,则需要首先检查密钥是否存在于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()

答案 5 :(得分:0)

试试这个:

    $foldername = '/photos/';
    $namep = $_FILES["images"]["name"];
    if (move_uploaded_file($_FILES["images"]["tmp_name"], $foldername . $namep)) {
        $output = array('uploaded' => 'OK');
    } else {
        $output = array('uploaded' => 'ERROR');
    }
    echo json_encode($output);

输出:

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()})

请注意,如果信号丢失,则只会将其视为零

答案 6 :(得分:0)

您可以尝试下面的代码

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。所以要注意这个限制