Python 如何对dict元素求和

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3490738/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:24:07  来源:igfitidea点击:

How to sum dict elements

pythondictionarysum

提问by Nazmul Hasan

In Python, I have list of dicts:

在 Python 中,我有字典列表:

dict1 = [{'a':2, 'b':3},{'a':3, 'b':4}]

I want one final dict that will contain the sum of all dicts. I.e the result will be: {'a':5, 'b':7}

我想要一个包含所有字典总和的最终字典。即结果将是:{'a':5, 'b':7}

N.B: every dict in the list will contain same number of key, value pairs.

注意:列表中的每个字典都将包含相同数量的键值对。

采纳答案by carl

A little ugly, but a one-liner:

有点丑,但单线:

dictf = reduce(lambda x, y: dict((k, v + y[k]) for k, v in x.iteritems()), dict1)

回答by paxdiablo

The following code shows one way to do it:

以下代码显示了一种方法:

dict1 = [{'a':2, 'b':3},{'a':3, 'b':4}]

final = {}
for k in dict1[0].keys():           # Init all elements to zero.
    final[k] = 0
for d in dict1:
    for k in d.keys():
        final[k] = final[k] + d[k]  # Update the element.

print final

This outputs:

这输出:

{'a': 5, 'b': 7}

as you desired.

如您所愿。

Or, as inspired by kriss, better but still readable:

或者,受 kriss 的启发,更好但仍然可读:

dict1 = [{'a':2, 'b':3},{'a':3, 'b':4}]

final = {}
for d in dict1:
    for k in d.keys():
        final[k] = final.get(k,0) + d[k]

print final

I pine for the days of the original, readable Python :-)

我怀念原始的、可读的 Python 的日子:-)

回答by Manoj Govindan

This might help:

这可能有帮助:

def sum_dict(d1, d2):
    for key, value in d1.items():
        d1[key] = value + d2.get(key, 0)
    return d1

>>> dict1 = [{'a':2, 'b':3},{'a':3, 'b':4}]
>>> reduce(sum_dict, dict1)
{'a': 5, 'b': 7}

回答by John La Rooy

Leveraging sum()should get better performance when adding more than a few dicts

sum()添加多个 dicts 时,利用杠杆应该会获得更好的性能

>>> dict1 = [{'a':2, 'b':3},{'a':3, 'b':4}]
>>> from operator import itemgetter
>>> {k:sum(map(itemgetter(k), dict1)) for k in dict1[0]}        # Python2.7+
{'a': 5, 'b': 7}
>>> dict((k,sum(map(itemgetter(k), dict1))) for k in dict1[0])  # Python2.6
{'a': 5, 'b': 7}

adding Stephan's suggestion

添加斯蒂芬的建议

>>> {k: sum(d[k] for d in dict1) for k in dict1[0]}            # Python2.7+
{'a': 5, 'b': 7}
>>> dict((k, sum(d[k] for d in dict1)) for k in dict1[0])      # Python2.6
{'a': 5, 'b': 7}

I think Stephan's version of the Python2.7 code reads really nicely

我认为 Stephan 版本的 Python2.7 代码读起来非常好

回答by SiggyF

You can use the collections.Counter

您可以使用collections.Counter

counter = collections.Counter()
for d in dict1: 
    counter.update(d)

Or, if you prefer oneliners:

或者,如果您更喜欢单线:

functools.reduce(operator.add, map(collections.Counter, dict1))

回答by Dave Kirby

In Python 2.7 you can replace the dict with a collections.Counterobject. This supports addition and subtraction of Counters.

在 Python 2.7 中,您可以用collections.Counter对象替换 dict 。这支持计数器的加法和减法。

回答by trudolf

I was interested in the performance of the proposed Counter, reduce and sum methods for large lists. Maybe someone else is interested in this as well. You can have a look here: https://gist.github.com/torstenrudolf/277e98df296f23ff921c

我对针对大型列表的建议 Counter、reduce 和 sum 方法的性能感兴趣。也许其他人也对此感兴趣。你可以看看这里:https: //gist.github.com/torstenrudolf/277e98df296f23ff921c

I tested the three methods for this list of dictionaries:

我为此字典列表测试了三种方法:

dictList = [{'a': x, 'b': 2*x, 'c': x**2} for x in xrange(10000)]

the sum method showed the best performance, followed by reduce and Counter was the slowest. The time showed below is in seconds.

sum 方法表现出最好的性能,其次是reduce,而Counter 是最慢的。下面显示的时间以秒为单位。

In [34]: test(dictList)
Out[34]: 
{'counter': 0.01955194902420044,
 'reduce': 0.006518083095550537,
 'sum': 0.0018319153785705566}

But this is dependent on the number of elements in the dictionaries. the sum method will slow down faster than the reduce.

但这取决于字典中的元素数量。sum 方法比reduce 慢得更快。

l = [{y: x*y for y in xrange(100)} for x in xrange(10000)]

In [37]: test(l, num=100)
Out[37]: 
{'counter': 0.2401433277130127,
 'reduce': 0.11110662937164306,
 'sum': 0.2256883692741394}

回答by Kyan

Here is a reasonable beatiful one.

这是一个合理的美丽的。

final = {}
for k in dict1[0].Keys():
    final[k] = sum(x[k] for x in dict1)
return final

回答by Aaron McMillin

One further one line solution

又一单线解决方案

dict(
    functools.reduce(
        lambda x, y: x.update(y) or x,  # update, returns None, and we need to chain.
        dict1,
        collections.Counter())
)

This creates only one counter, uses it as an accumulator and finally converts back to a dict.

这仅创建一个计数器,将其用作累加器,最后转换回 dict。

回答by Ste

Here is another working solution (python3), quite general as it works for dict, lists, arrays. For non-common elements, the original value will be included in the output dict.

这是另一个工作解决方案(python3),非常通用,因为它适用于字典、列表、数组。对于非公共元素,原始值将包含在输出字典中。

def mergsum(a, b):
    for k in b:
        if k in a:
            b[k] = b[k] + a[k]
    c = {**a, **b}
    return c

dict1 = [{'a':2, 'b':3},{'a':3, 'b':4}]
print(mergsum(dict1[0], dict1[1]))