2013-05-25 4 views
0

Для списка списков существует какой-то способ суммирования столбца для каждого конкретного элемента в списке (с использованием python). Пример ...Сумма столбца в списке в списке для каждого элемента

l=[['A1','1','2'],['A1','1','2'],['A1','3','3'],['B1','1','2'],['B1','5','5'],[...]] 

Теперь суммируем первый столбец только для A1, и т.д B1 и получить желаемый результат, как ...

sumA1=5 
sumB1=6 
sumC1....... 

Теперь список значений может измениться, так что я не» t хочу ссылку на «A1, B1 ..». Это может стать A3, B4 .... так что лучший способ - суммировать по индексу [0] (число/тип столбцов не изменится). код у меня есть атм просто простой список понимание, что суммирует все колонки 1, независимо от того, A1, B1, и т.д ..

for i in l: 
    total = sum(float(i[1]) for i in l if i[1]) 

Учитывая, что всегда будет одинаковое количество элементов для каждого «A1, B1 .. »скажем, 10, альтернативой было бы суммировать каждые 10 чисел в i [1], но тогда мне нужно было бы сказать« сумма 1-го 10 чисел для A1, сумма 2-го 10 номеров - B2 и т. Д. ». Цените помощь

ответ

3

Группируйте элементы в первом столбце в словаре; defaultdict делает это немного легче:

from collections import defaultdict 

sums = defaultdict(int) 

for tup in l: 
    sums[tup[0]] += int(tup[1]) 

defaultdict просто называет переданные на заводе по производству значения по умолчанию, если ключ не присутствует (int в этом случае, производя 0):

>>> d = defaultdict(int) 
>>> d['foo'] 
0 

Демо:

>>> l=[['A1','1','2'],['A1','1','2'],['A1','3','3'],['B1','1','2'],['B1','5','5']] 
>>> from collections import defaultdict 
>>> sums = defaultdict(int) 
>>> for tup in l: 
...  sums[tup[0]] += int(tup[1]) 
... 
>>> sums 
defaultdict(<class 'int'>, {'B1': 6, 'A1': 5}) 

Затем печать суммы так же просто, как:

for key in sorted(sums): 
    print 'sum{}={}'.format(key, sums[key]) 

Если ваш список входов отсортирован используйте itertools.groupby():

from itertools import groupby 
from operator import itemgetter 

sums = {key: sum(int(t[1]) for t in group) for key, group in groupby(l, key=itemgetter(0))} 

Демо:

>>> from itertools import groupby 
>>> from operator import itemgetter 
>>> {key: sum(int(t[1]) for t in group) for key, group in groupby(l, key=itemgetter(0))} 
{'B1': 6, 'A1': 5} 

В самом деле, с отсортированного списка и groupby вы можете переключиться прямо на печать:

for key, group in groupby(l, key=itemgetter(0)): 
    print 'sum{}={}'.format(key, sum(t[1]) for t in group)) 

Без внешних модулей я бы просто пошел на словарь; это будет медленнее, чем любой из вышеперечисленных вариантов:

sums = {} 

for tup in l: 
    sums[tup[0]] = sums.get(tup[0], 0) + int(tup[1]) 

или, для отсортированного варианта:

sum, last = 0, l[0][0] 
for tup in l: 
    key = tup[0] 
    if last != key and sum: 
     print 'sum{}={}'.format(last, sum) 
     sum, last = 0, key 
    sum += int(tup[1]) 
if sum: 
    print 'sum{}={}'.format(key, sum) 
+0

бах лучше, чем у меня снова :((+1) ... –

+0

Они выглядят хорошо, но по умолчанию является обязательным или может быть сделано в цикле for? –

+0

Я слепой, просто заметил цикл for.Так что делает defaultdict на самом деле, если элемент уже отсортирован? –

0
>>> from collections import defaultdict 
>>> a = [["a",1,2],["a",2,3],["b",45,2]] 
>>> my_dict = defaultdict(list) 
>>> for itm in a: 
... my_dict[itm[0]].append(itm) 
... 
>>> for k,v in my_dict.items(): 
... print "Sum %s:%s"%(k,sum(zip(*v)[1])) 
... 
Sum a:3 
Sum b:45 
Смежные вопросы