如何合并一个dicts列表,为重复键求和值

时间:2016-04-21 03:15:56

标签: python

在这个词典列表中,我想总结一下匹配键的values,以便输出如下所示:

dict_x = [{(1, 2): 100}, {(1, 3): 150}, {(1, 3): 150, (3, 4): 150}, {(4, 5): 10, (1, 3): 10, (3, 4): 10},  {(5, 6): 15}]

output:{(1, 2): 100, (1, 3): 310, (3, 4): 160, (4, 5): 10, (5, 6): 15}

我已经阅读了How can I count the occurrences of a list item in Python?Count how many times a part of a key appears in a dictionary python这样的页面,当他们计算匹配元素的出现时,他们并没有对匹配元素进行多次求和。谢谢你的时间。

4 个答案:

答案 0 :(得分:2)

以下是使用collections.Counter一次通过的方法:

>>> from collections import Counter
>>> sum(map(Counter, dict_x), Counter())
Counter({(1, 2): 100, (1, 3): 310, (3, 4): 160, (4, 5): 10, (5, 6): 15})

之前的回复:

也许不是最有效的方式,但对于一个小清单,你可以通过两次通过:

>>> keys = [k for d in dict_x for k in d]
>>> {k: sum(d.get(k, 0) for d in dict_x) for k in keys}
{(1, 2): 100, (1, 3): 310, (3, 4): 160, (4, 5): 10, (5, 6): 15}

第一行获取所有键,第二行合并结果。我几乎是积极的,有一些更聪明的方法来使用python内置的...我会考虑它。

答案 1 :(得分:1)

out_dict = {}
for a in dict_x:
        for b in a.keys():
                out_dict[b] = out_dict.get(b, 0) + a[b]

print out_dict

答案 2 :(得分:1)

对于一个小列表,Counter 工作正常并且看起来像 Python 一样,但是如果你有一个庞大的字典列表,Counter 就会停止工作。在这种情况下,这是一种可能的解决方案。

%%timeit
from functools import reduce

a = {'a': 2, 'b':3, 'c':4}
b = {'a': 5, 'c':6, 'x':7}

dict_list = [a, b]

def combine_dicts(d1, d2):
  d = d1.copy()
  for word, count in d2.items():
    d[word] = d.get(word,0) + count
  return d  

final_dict = reduce(combine_dicts, dict_list)
# output
1.49 µs ± 19.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

为了比较,这里是使用 Counter 的结果

%%timeit
from collections import Counter

a = {'a': 2, 'b':3, 'c':4}
b = {'a': 5, 'c':6, 'x':7}
dict_list = [a,b]
final_dict = sum(map(Counter, dict_list), Counter())
#output
7.95 µs ± 87.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

答案 3 :(得分:0)

这里有一个可能的解决方案(foo可以进一步优化):

dict_x = [{(1, 2): 100}, {(1, 3): 150}, {(1, 3): 150, (3, 4): 150}, {(4, 5): 10, (1, 3): 10, (3, 4): 10},  {(5, 6): 15}]
new_dict_x = {}

def foo(x):
    global new_dict_x
    for item in x.keys():
        new_dict_x[item] = new_dict_x.get(item, 0) + x[item]

list(map(lambda x: foo(x),dict_x))

print('Input: {}'.format(dict_x))
print('Output: {}'.format(new_dict_x))

输出:

Input: [{(1, 2): 100}, {(1, 3): 150}, {(1, 3): 150, (3, 4): 150}, {(4, 5): 10, (1, 3): 10, (3, 4): 10}, {(5, 6): 15}]
Output: {(1, 2): 100, (4, 5): 10, (5, 6): 15, (1, 3): 310, (3, 4): 160}