假设我有一个清单:
l = [{"num1":3, "num2":8, "num3":5, "type":"A"}, {"num1":2, "num2":5, "num3":5, "type":"B"}, {"num1":5, "num2":2, "num3":1, "type":"A"}, {"num1":4, "num2":4, "num3":9, "type":"B"}
我想创建2个词典: SUMA:
{"num1":8, "num2":10, "num3":6}
sumB:
{"num1":6, "num2":9, "num3":14}
我希望尽可能简单易读。 我设法用太多变量以可怕的方式做到了......
谢谢!
答案 0 :(得分:1)
使用一些list and dict comprehensions可以很容易地做到这一点。
from operator import itemgetter
from itertools import groupby
l = [{"num1": 3, "num2": 8, "num3": 5, "type": "A"},
{"num1": 2, "num2": 5, "num3": 5, "type": "B"},
{"num1": 5, "num2": 2, "num3": 1, "type": "A"},
{"num1": 4, "num2": 4, "num3": 9, "type": "B"}]
wanted_values = {"num1", "num2", "num3"}
type_getter = itemgetter("type")
groups = [(group, list(items)) for group, items in
groupby(sorted(l, key=type_getter), type_getter)]
print({group: {k: sum(map(itemgetter(k), items)) for k in wanted_values}
for group, items in groups})
这给了我们:
{'B': {'num2': 9, 'num3': 14, 'num1': 6},
'A': {'num2': 10, 'num3': 6, 'num1': 8}}
我们按类型对值进行排序,然后将它们分成itertools.groupby()
组(使项目列表而不是生成器,因为我们需要多次迭代它们)。
然后我们使用嵌套的字典理解来创建我们需要的数据,将项目中的值相加并将它们分配给一个组。
这是一个灵活的解决方案,可以扩展到只有两种类型。
答案 1 :(得分:0)
我会使用嵌套理解。
lst = [{"num1": 3, "num2": 8, "num3": 5, "type": "A"},
{"num1": 2, "num2": 5, "num3": 5, "type": "B"},
{"num1": 5, "num2": 2, "num3": 1, "type": "A"},
{"num1": 4, "num2": 4, "num3": 9, "type": "B"}]
sum_by_a = {key: sum(d[key] for d in lst if d['type'] == 'A')
for key in ("num1", "num2", "num3")}
或者,对于泛型类型,
sum_by_type = lambda t: {
key: sum(d[key] for d in lst if d['type'] == t)
for key in ("num1", "num2", "num3")}
sum_by_b = sum_by_type(B)
答案 2 :(得分:0)
我会这样做,使用Collections.Counter
:
from collections import Counter
from functools import reduce
l = [{"num1":3, "num2":8, "num3":5, "type":"A"},
{"num1":2, "num2":5, "num3":5, "type":"B"},
{"num1":5, "num2":2, "num3":1, "type":"A"},
{"num1":4, "num2":4, "num3":9, "type":"B"}]
def remove_keys(d, keys):
return {i: j for i, j in d.items() if i not in keys}
def add_dicts(dicts):
return reduce(lambda a, b: a+b, map(Counter, dicts))
tmp = {}
for d in l:
tmp[d["type"]] = tmp.get(d["type"], []) + [remove_keys(d, ["type"])]
result = {key: add_dicts(value) for key, value in dict(tmp).items()}
给出:
{'A': Counter({'num2': 10, 'num1': 8, 'num3': 6}),
'B': Counter({'num3': 14, 'num2': 9, 'num1': 6})}