如何对 python 中的 Counter 的 Counter 求和?

How to sum Counter of Counter in python?

我有一个列表,其中的元素是 Counter of Counter。例如:

l = [Counter({'a': Counter({'aa': 1, 'bb': 2}), 'b': Counter({'aa': 3, 'cc':4})}),
     Counter({'a': Counter({'aa': 5, 'cc': 6}), 'c': Counter({'aa': 7, 'bb':8})})]

我希望将两个计数器相加,即我希望得到以下结果:

result = Counter({'a': Counter({'aa': 6, 'bb':2, 'cc': 6}),
                  'b': Counter({'aa': 3, 'cc':4}),
                  'c': Counter({'aa': 7, 'bb':8})})

为了得到这个,我尝试按如下方式直接求和 l

result = sum(l, Counter())

但它返回错误,

TypeError: unsupported operand type(s) for +: 'Counter' and 'int'.

有什么办法可以解决吗?

您可以使用集合的 defaultdict 作为累加器而不是 Counter:

from collections import defaultdict, Counter

l = [Counter({'a': Counter({'aa': 1, 'bb': 2}), 'b': Counter({'aa': 3, 'cc':4})}),
     Counter({'a': Counter({'aa': 5, 'cc': 6}), 'c': Counter({'aa': 7, 'bb':8})})]

def aggregate_counters(acc, counter):
    extended = {x: acc[x] + counter[x] for x in counter}
    new_val = {**acc, **extended}
    return defaultdict(Counter, new_val)


reduce(aggregate_counters, l, defaultdict(Counter))

将给予:

defaultdict(collections.Counter,
            {'a': Counter({'aa': 6, 'bb': 2, 'cc': 6}),
             'b': Counter({'aa': 3, 'cc': 4}),
             'c': Counter({'aa': 7, 'bb': 8})})

创建一个新计数器并将所有现有计数器内容添加到其中。 字典 class 有一个可用于此目的的更新方法:

from collections import Counter

l = [Counter({'a': Counter({'aa': 1, 'bb': 2}), 'b': Counter({'aa': 3, 'cc':4})}),
    Counter({'a': Counter({'aa': 5, 'cc': 6}), 'c': Counter({'aa': 7, 'bb':8})})]

result = Counter()

for counter in l:
    for key, value in counter.items():
        result.setdefault(key, Counter()).update(value) # update key by value's

print(result)

输出:

Counter({'a': Counter({'aa': 6, 'cc': 6, 'bb': 2}),
         'b': Counter({'cc': 4, 'aa': 3}),
         'c': Counter({'bb': 8, 'aa': 7})}) 

一个简单的解决方案,适用于不具备所有 python 词典核心知识的初学者:

解法:

l = [Counter({'a': Counter({'aa': 1, 'bb': 2}), 'b': Counter({'aa': 3, 'cc':4})}),
     Counter({'a': Counter({'aa': 5, 'cc': 6}), 'c': Counter({'aa': 7, 'bb':8})})]

returnval={}

for counters in l:
    for key, value in counters.items():
        if key not in returnval:
            returnval[key] = value
        else:
            returnval[key] = returnval[key].__add__(value)

print returnval

参考:https://docs.python.org/3/library/collections.html#collections.Counter

示例: 将两个计数器的计数相加。

>>> Counter('abbb') + Counter('bcc')
Counter({'b': 4, 'c': 2, 'a': 1})

>>> a=Counter({'aa': 1, 'bb': 2})
>>> b= Counter({'aa': 3, 'cc':4})
>>> print a.__add__(b)
Counter({'aa': 4, 'cc': 4, 'bb': 2})