【问题标题】:Python merge two counter objects, keeping the largest sumPython合并两个计数器对象,保持最大的和
【发布时间】:2016-11-24 07:24:20
【问题描述】:

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

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} 

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

【问题讨论】:

  • 您的问题是“添加新值”,但您想要的输出只包含常见的。
  • @DeepSpace 你是对的,我已经有了两个计数器的交集,但我也想添加独特的项目。我希望这能澄清最初的问题。
  • @user1610950 编辑您的问题时,删除错误并保留更正的版本是完全可以接受的(只需编辑代码的最后一行) - 您不必维护旧的并添加一个编辑部分。如果你想这样做是可以的,但对于问题的未来读者来说,如果只是纠正它可能会更清楚。
  • @Matthew 谢谢,我做了建议的编辑。 DeepSpace,谢谢,这是一个非常简洁的答案。

标签: python counter


【解决方案1】:

在 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})

【讨论】:

  • @Akaberto 你是什么意思?
  • 如按位或给出 1|4 == 5
  • @Akaberto 自己尝试一下,你会发现它有效。
  • 错过了这个运算符为此重载。我的错。只是在想多么正常的'|'操作员工作。按位计算。
  • 根据问题中提供的示例,"kiwi" 不应出现在结果计数器中。问题是要求保持 -maximum- 值而不是最小值的交集,就像 Python 默认做的那样。
【解决方案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})
>>> 

【讨论】:

    【解决方案3】:

    您可以获取两个计数器中键的交集并在字典理解中对其进行迭代,同时使用 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})
    

    【讨论】:

      【解决方案4】:

      除了接受的答案之外,如果您有任意多个计数器要合并,您可以将__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})

      【讨论】:

        猜你喜欢
        • 2016-05-25
        • 2017-12-12
        • 1970-01-01
        • 2021-02-26
        • 2013-09-23
        • 1970-01-01
        • 1970-01-01
        • 2013-01-28
        • 2014-11-29
        相关资源
        最近更新 更多