簡體   English   中英

按屬性聚合對象數組

[英]aggregating an array of objects by attribute

我有一個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

有人有什么建議嗎?

使用itertools.groupby

>>> 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. 根據foo值對bar值進行分組並添加它們。

     >>> grouper = {} >>> for d in data: ... grouper[d["foo"]] = grouper.get(d["foo"], 0) + d["bar"] ... >>> grouper {34: 5, 35: 10} 
  2. 然后用列表理解重建dicts列表,就像這樣

     >>> [{"foo": item, "bar": grouper[item]} for item in grouper] [{'foo': 34, 'bar': 5}, {'foo': 35, 'bar': 10}] 

此解決方案使用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是一個defaultdict,值為'foo'作為鍵,值'bar'作為值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM