python字典值求和_关于python:如何对dict元素求和

在python中,我有口述清单:

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

我想要一个包含所有口述总和的最终口述。即结果为:{'a':5, 'b':7}。

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

您可以使用Collections.Counter

1

2

3counter = collections.Counter()

for d in dict1:

counter.update(d)

或者,如果您更喜欢一行:

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

或sum(map(collections.Counter, dict1),Counter())。但我不确定创建所有这些Counters()的功能版本的相对性能。

这个答案展示了Python编程的黄金法则:如果它包含在Python中,就不要重新发明轮子。一点:最终结果counter是dict子类的一个实例,如果OP想要一个普通的dict子类,他可以添加一个最终的counter = dict(counter)。

+1代表Python!!!!

如果dict不都有相同的键,则第一个解决方案将只输出所有dict之间共享的键的结果,而第二个一行解决方案将输出所有键的结果(将缺少的键视为值0)。

有点难看,但只有一行:

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

实际上我有一个对象列表,这个字典是一个对象属性,有什么解决方案吗?:(

我不知道你什么意思?

[ob1,ob2,ob3]。每个对象都有一个属性数据ob1.data,它返回dict'a':2,'b':3之类的

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

我的代码通过这个解决方案工作..好…减少(lambda x,y:dict((k,v+y.get_local_expenses()[k]如果不存在(y.get_local_expenses()[k],dict)否则0)对于k,v in x.get_local_expenses().iteritems(),glc)

@纳兹穆尔哈桑:你能在6个月内理解这一点吗?您已经写了三次get_local_expenses()这是必要的吗?什么是GLC?你读过@paxdiablo的答案了吗?

也许我的答案唯一的好处是它使用了一些很酷的概念:reduce、lambda、生成器表达式和迭代器。

@john machin:glc是一个对象列表get_local_expense()是每个对象的一个属性,返回一个字典字典值可能是另一个dict或str值或decimal值…..我已经阅读了@paxdiablo的ans,我在他面前解决了它,但我喜欢一个线性解决方案:)

当添加多个dict时,利用sum()应该可以获得更好的性能。

1

2

3

4

5

6>>> 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}

添加Stephan的建议

1

2

3

4>>> {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}

我认为斯蒂芬版本的python2.7代码读起来非常好

你在内环使用map和itemgetter而不是列表理解(即dict((k, sum(d[k] for d in dict1)) for k in dict1[0]))有什么原因吗?

@史蒂芬,以前速度更快……现在速度差不多了。我会把它加到我的答案里

谢谢,我不知道。+ 1

这个版本的一个很好的补充,它还检查了dict类型,确保我们可以在它们上面进行数学运算:{k: sum(d[k] if type(d[k]) in (int, float) else 0 for d in dict1) for k in dict1[0]}。

这可能有助于:

1

2

3

4

5

6

7

8def 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}

下面的代码显示了一种方法:

1

2

3

4

5

6

7

8

9

10dict1 = [{'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

此输出:

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

如你所愿。

或者,受克里斯启发,更好但仍然可读:

1

2

3

4

5

6

7

8dict1 = [{'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

我渴望看到原始的、可读的python:-)

您可以将第一个for循环简化为final={}.fromkeys(dict1[0],0)。或者这就是"可读"的意思?:)

我可以把整个事情简化成卡尔的答案,但这意味着(1)我也可以删除我的答案;(2)下个月当我发现我需要一个小的改变时,我将看不到它:(1)我应该提到我使用Python来教学(我的Python品牌,而不是卡尔的品牌)。它确实是一种很好的语言,可以教孩子们基础知识(顺序、迭代、选择),但是,如果你想用lambdas之类的东西把他们打到脑后,你也可以教他们f_或haskell。

@paxdiablo:为了可读性,您可以完全删除init循环,只需用+ res.get(k, 0)替换+ d[k]。

这是一个很好的版本,@kris,仍然非常可读,但我认为你的意思是用final.get(k,0) + d[k]替换final[k] + d[k]--如果密钥不存在,我需要的是final字典--我知道它是d的列表。

@帕克迪亚布洛:乌普斯!是的,你是绝对正确的,我把措辞颠倒了。

@帕西迪亚布洛:你甚至可以更进一步(但我想知道可读性,你自己看)。用final = dict((k, v + final.get(k, 0)) for k, v in d.iteritems())更换内环

现在开始看起来像"_"?να_?να,?χαχλ_?μετρομακρ_ν??απ?εδ?"像有用的,但不太容易理解(除非你沉浸在语言中)。

我对建议的计数器的性能很感兴趣,大列表的约简和方法。也许还有人对此感兴趣。您可以在这里查看:https://gist.github.com/torstenrudolf/277e98df296f23f921c

我测试了这组词典的三种方法:

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

求和法的性能最好,其次是约简法,计数器法最慢。下面显示的时间以秒为单位。

1

2

3

4

5In [34]: test(dictList)

Out[34]:

{'counter': 0.01955194902420044,

'reduce': 0.006518083095550537,

'sum': 0.0018319153785705566}

但这取决于字典中元素的数量。求和法比减法慢。

1

2

3

4

5

6

7l = [{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}

这是一个合理而美丽的。

1

2

3

4final = {}

for k in dict1[0].Keys():

final[k] = sum(x[k] for x in dict1)

return final

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

但它适用于2.7版

在python 3中呢?

另一个单线解决方案

1

2

3

4

5

6dict(

functools.reduce(

lambda x, y: x.update(y) or x, # update, returns None, and we need to chain.

dict1,

collections.Counter())

)

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

你可能感兴趣的:(python字典值求和)