Группировка списка кортежа 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 / изящно / эффективный способ сделать это?

21
задан hoju 12 February 2010 в 01:43
поделиться

4 ответа

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)]
>>> 
32
ответ дан 29 November 2019 в 20:03
поделиться

с использованием 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) .

6
ответ дан 29 November 2019 в 20:03
поделиться
import collections
d=collections.defaultdict(int)
a=[]
alist=[('grape', 100), ('banana', 3), ('apple', 10), ('apple', 4), ('grape', 3), ('apple', 15)]
for fruit,number in alist:
    if not fruit in a: a.append(fruit)
    d[fruit]+=number
for f in a:
    print (f,d[f])

output

$ ./python.py
('grape', 103)
('banana', 3)
('apple', 29)
5
ответ дан 29 November 2019 в 20:03
поделиться
>>> from itertools import groupby
>>> from operator import itemgetter
>>> L=[('grape', 100), ('grape', 3), ('apple', 15), ('apple', 10), ('apple', 4), ('banana', 3)]
>>> [(x,sum(map(itemgetter(1),y))) for x,y in groupby(L, itemgetter(0))]
[('grape', 103), ('apple', 29), ('banana', 3)]
4
ответ дан 29 November 2019 в 20:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: