分组 Python 元组列表

新手上路,请多包涵

我有一个这样的(标签,计数)元组列表:

 [('grape', 100), ('grape', 3), ('apple', 15), ('apple', 10), ('apple', 4), ('banana', 3)]

由此我想用相同的标签(相同的标签总是相邻的)对所有值求和,并以相同的标签顺序返回一个列表:

 [('grape', 103), ('apple', 29), ('banana', 3)]

我知道我可以用类似的方法解决它:

 def group(l):
    result = []
    if l:
        this_label = l[0][0]
        this_count = 0
        for label, count in l:
            if label != this_label:
                result.append((this_label, this_count))
                this_label = label
                this_count = 0
            this_count += count
        result.append((this_label, this_count))
    return result

但是有没有更Pythonic/优雅/高效的方法来做到这一点?

原文由 hoju 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 642
2 个回答

itertools.groupby 可以做你想做的事:

 import itertools
import operator

L = [('grape', 100), ('grape', 3), ('apple', 15), ('apple', 10),
     ('apple', 4), ('banana', 3)]

def accumulate(l):
    it = itertools.groupby(l, operator.itemgetter(0))
    for key, subiter in it:
       yield key, sum(item[1] for item in subiter)

print(list(accumulate(L)))
# [('grape', 103), ('apple', 29), ('banana', 3)]

原文由 Thomas Wouters 发布,翻译遵循 CC BY-SA 4.0 许可协议

使用 itertools 和列表理解

import itertools

[(key, sum(num for _, num in value))
    for key, value in itertools.groupby(l, lambda x: x[0])]

编辑: 正如 gnibbler 指出的那样:如果 l 尚未排序,则将其替换为 sorted(l)

原文由 cobbal 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题