我有一个动态增长的数组列表,我想将它们像值一起添加。这是一个例子:
{"something" : [{"one":"200"}, {"three":"400"}, {"one":"100"}, {"two":"800"} ... ]}
我希望能够将列表中的词典加在一起。因此,在这种情况下,对于关键的“某事”,结果将是:
["one":400, "three": 400, "two": 800]
或其他相似之处。我熟悉Python的集合计数器,但由于“某事”列表包含dicts,它不起作用(除非我遗漏了一些东西)。 dict也是动态创建的,所以我不能在没有dicts的情况下构建列表。 EG:
Counter({'b':3, 'c':4, 'd':5, 'b':2})
通常会有效,但只要我尝试添加元素,就会覆盖之前的值。我注意到了其他问题:
Is there any pythonic way to combine two dicts (adding values for keys that appear in both)?
Python count of items in a dictionary of lists
但同样,列表中的对象是dicts。
答案 0 :(得分:8)
我认为这可以做你想要的,但我不确定,因为我不知道什么" dict也是动态创建的,所以我无法构建列表没有dicts"手段。仍然:
input = {
"something" : [{"one":"200"}, {"three":"400"}, {"one":"100"}, {"two":"800"}],
"foo" : [{"a" : 100, "b" : 200}, {"a" : 300, "b": 400}],
}
def counterize(x):
return Counter({k : int(v) for k, v in x.iteritems()})
counts = {
k : sum((counterize(x) for x in v), Counter())
for k, v in input.iteritems()
}
结果:
{
'foo': Counter({'b': 600, 'a': 400}),
'something': Counter({'two': 800, 'three': 400, 'one': 300})
}
我希望sum
与Counter
一起使用是效率低的(与使用sum
字符串的方式相同,Guido禁止它的效率非常低),但我可能错了。无论如何,如果您遇到性能问题,可以编写一个创建Counter
并在其上反复调用+=
或update
的函数:
def makeints(x):
return {k : int(v) for k, v in x.iteritems()}
def total(seq):
result = Counter()
for s in seq:
result.update(s)
return result
counts = {k : total(makeints(x) for x in v) for k, v in input.iteritems()}
答案 1 :(得分:1)
一种方法如下:
from collections import defaultdict
d = {"something" :
[{"one":"200"}, {"three":"400"}, {"one":"100"}, {"two":"800"}]}
dd = defaultdict(list)
# first get and group values from the original data structure
# and change strings to ints
for inner_dict in d['something']:
for k,v in inner_dict.items():
dd[k].append(int(v))
# second. create output dictionary by summing grouped elemetns
# from the first step.
out_dict = {k:sum(v) for k,v in dd.items()}
print(out_dict)
# {'two': 800, 'one': 300, 'three': 400}
在这里我不使用counter,而是使用defaultdict。它是一个两步走的方法。