Python合并两个计数器对象,保持最大的总和

Python merge two counter objects, keeping the largest sum

如果我有两个计数器对象并且我想合并它们,从一个中添加新值并在两个计数器包含相同值时保持最大计数。

Counter a = { "apple":3, "peach":1, "pears":7, "watermelon":2, "grapes":7 }

Counter b = { "apple":12, "kiwi":9, "grapes":2, "pears":21, "pineapple":2, "oranges":2 }

#desired output
counter c = { "apple":12, "pears":21, "grapes":7 "peach":1, "watermelon":2, "pineapple":2, "oranges":2} 

目前我已经尝试更新计数器,但这似乎合并了两个计数器但将它们的计数相加。我只想合并计数器并保留最大值或添加到计数器(如果还没有)。

您可以使用内置 a&b 从每个 Counter 中获取不同的键,并使用它们来获得您想要的最大逻辑,如下所示:

Counter({key:max(a[key], b[key]) for key in a&b})

这是一个示例 运行:

>>> from collections import Counter
>>> a=Counter({ "apple":3, "peach":1, "pears":7, "watermelon":2, "grapes":7 })
>>> b=Counter({ "apple":12, "kiwi":9, "grapes":2, "pears":21, "pineapple":2, "oranges":2 })
>>> Counter({key:max(a[key], b[key]) for key in a&b})
Counter({'pears': 21, 'apple': 12, 'grapes': 7})
>>> 

请注意,如果您想要使用此构造在 python 中构建的公共元素的最小值:

>>> a&b
Counter({'pears': 7, 'apple': 3, 'grapes': 2})
>>> 

您可以取两个计数器中键的交集并在字典理解中对其进行迭代,同时使用 max 获得最大值:

>>> a = Counter({ "apple":3, "peach":1, "pears":7, "watermelon":2, "grapes":7 })
>>> b = Counter({ "apple":12, "kiwi":9, "grapes":2, "pears":21, "pineapple":2, "oranges":2 })
>>> Counter({k: max(a[k], b[k]) for k in a.keys() & b.keys()})
Counter({'pears': 21, 'apple': 12, 'grapes': 7})

请注意,以上仅适用于 Python 3,在 Python 2 上您需要调用 viewkeys

>>> Counter({k: max(a[k], b[k]) for k in a.viewkeys() & b.viewkeys()})
Counter({'pears': 21, 'apple': 12, 'grapes': 7})

OP 编辑​​他们的问题后,只需使用按位或 ('|') 运算符即可获得所需的输出:

from collections import Counter

a = Counter({ "apple":3, "peach":1, "pears":7, "watermelon":2, "grapes":7 })

b = Counter({ "apple":12, "kiwi":9, "grapes":2, "pears":21, "pineapple":2, "oranges":2 })

c = a | b

print(c)
>> Counter({'pears': 21, 'apple': 12, 'kiwi': 9, 'grapes': 7, 'watermelon': 2, 'oranges': 2,
            'pineapple': 2, 'peach': 1})

除了已接受的答案之外,如果您有任意多个要合并的计数器,您可以将 __or__ 运算符与 reduce 结合使用,如下所示:

from functools import reduce
from collections import Counter

a = Counter({ "apple":3, "peach":1, "pears":7, "watermelon":2, "grapes":7 })
b = Counter({ "apple":12, "kiwi":9, "grapes":2, "pears":21, "pineapple":2, "oranges":2 })
counters = [a,b]

c = reduce(Counter.__or__, counters)

print(c)

给你:Counter({'pears': 21, 'apple': 12, 'kiwi': 9, 'grapes': 7, 'watermelon': 2, 'pineapple': 2, 'oranges': 2, 'peach': 1})