我有一个dicts列表,每个都有两个键/值对。我需要通过对第二个键的值进行求和来组合第一个键共享相同值的词组。例如:
[
{'foo': 34, 'bar': 2},
{'foo': 34, 'bar': 3},
{'foo': 35, 'bar': 1},
{'foo': 35, 'bar': 7},
{'foo': 35, 'bar': 2}
]
会出现:
[
{'foo': 34, 'bar': 5},
{'foo': 35, 'bar': 10}
]
我编写了以下函数,该函数有效,但看起来非常冗长,我几乎可以肯定有一个很酷的pythonic技巧会更干净,性能更高。
def combine(arr):
arr_out = []
if arr:
arr_out.append({'foo': arr[0]['foo'], 'bar': 0})
for i in range(len(arr)):
if arr[i]['foo'] == arr_out[-1]['foo']:
arr_out[-1]['bar'] += arr[i]['bar']
else:
arr_out.append({'foo': arr[i]['foo'], 'bar': arr[i]['bar']})
return arr_out
有人有任何建议吗?
答案 0 :(得分:5)
>>> arr = [
... {'foo': 34, 'bar': 2},
... {'foo': 34, 'bar': 3},
... {'foo': 35, 'bar': 1},
... {'foo': 35, 'bar': 7},
... {'foo': 35, 'bar': 2}
... ]
>>> import itertools
>>> key = lambda d: d['foo']
>>> [{'foo': key, 'bar': sum(d['bar'] for d in grp)}
... for key, grp in itertools.groupby(sorted(arr, key=key), key=key)]
[{'foo': 34, 'bar': 5}, {'foo': 35, 'bar': 10}]
如果列表已经排序,您可以省略sorted
电话:
>>> [{'foo': key, 'bar': sum(d['bar'] for d in grp)}
... for key, grp in itertools.groupby(arr, key=key)]
[{'foo': 34, 'bar': 5}, {'foo': 35, 'bar': 10}]
答案 1 :(得分:3)
根据bar
值对foo
值进行分组并添加。
>>> grouper = {}
>>> for d in data:
... grouper[d["foo"]] = grouper.get(d["foo"], 0) + d["bar"]
...
>>> grouper
{34: 5, 35: 10}
然后用列表理解重建dicts列表,就像这样
>>> [{"foo": item, "bar": grouper[item]} for item in grouper]
[{'foo': 34, 'bar': 5}, {'foo': 35, 'bar': 10}]
答案 2 :(得分:0)
此解决方案使用collections.defaultdict
:
def combine(arr):
c = collections.defaultdict(int)
for i in arr:
c[i['foo']] += i['bar']
# c == {34: 5, 35: 10}
return [{'foo': k, 'bar': c[k]} for k in sorted(c)]
字典c
是默认字典,值为' foo'作为' bar'的关键和价值。作为价值。