【问题标题】:Convert key value pairs with duplicate keys into a Counter将具有重复键的键值对转换为计数器
【发布时间】:2017-04-03 01:26:06
【问题描述】:

我在 Python 2.7 中有这个

l = [('a', 1), ('a', 2), ('b', 3), ('b', 4)]

我如何获得一个 Counter c where:

c = Counter({'a': 3, 'b': 7 }]

如果可能,我更愿意使用理解或最快的方式来做到这一点。

【问题讨论】:

  • 好奇:为什么你更喜欢理解?

标签: python python-2.7 collections


【解决方案1】:

只需迭代和添加,Counter 会自动处理这个问题!

In [5]: l = [('a', 1), ('a', 2), ('b', 3), ('b', 4)]
    ...:

In [6]: c = Counter()

In [7]: for k, v in l:
    ...:     c[k] += v
    ...:

In [8]: c
Out[8]: Counter({'a': 3, 'b': 7})

Counter 就是这样设计的。

【讨论】:

    【解决方案2】:

    另一种方法:

    >>> from operator import add
    >>> reduce(add, map(lambda x: Counter({x[0]: x[1]}), l))
    Counter({'b': 7, 'a': 3})
    

    sum:

    >>> sum(map(lambda x: Counter({x[0]: x[1]}), l), Counter())
    Counter({'b': 7, 'a': 3})
    

    【讨论】:

    • 使用sum 代替reduceoperator.add
    • 我尝试了sum(map(lambda x: Counter({x[0]: x[1]}), l)),但得到了TypeError: unsupported operand type(s) for +: 'int' and 'Counter',然后改用reduceoperator.add。刚刚发现需要为sum指定默认的start参数。感谢您的信息,我更新了我的答案:-)
    【解决方案3】:

    按键排序和分组;对每个键的值求和;将 key:sum(values) 添加到字典中。

    >>> import operator
    >>> a = [('a', 1), ('a', 2), ('b', 3), ('b', 4)]
    >>> key = operator.itemgetter(0)
    >>> value = operator.itemgetter(1)
    >>> a.sort(key = key)
    >>> d = {}
    >>> for k, group in itertools.groupby(a, key = key):
        d[k] = sum(map(value, group))
    
    >>> d
    {'a': 3, 'b': 7}
    >>> 
    

    >>> g = {k:sum(map(value, group)) for k, group in itertools.groupby(a, key = key)}
    >>> g
    {'a': 3, 'b': 7}
    >>> 
    

    你真的不需要 collections.Counter

    【讨论】:

    • 绝对不需要itertools.groupbysort!只需使用setdefaultget(x, 0)! ...或者只使用Counter
    • 同意,但我喜欢 itertools。
    • 当然,但是您正在用 O(n) 解决方案换取 O(n*logn) 解决方案...也许不是世界末日...
    • 好吧,如果这是一个糟糕的解决方案,那么减一就可以了。
    猜你喜欢
    • 2023-03-04
    • 2020-11-26
    • 2018-08-07
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多