如何对 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})
我有一个列表,其中的元素是 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})