2016-11-21 5 views
1

У меня есть список кортежей:Python группы и сумма

Listoftuples=[ 
    (0.021892733407683305, 0.14887058717224647, 4.573173081530965, 0.04619366749021177, u'0102'), 
    (0.08416364174734663, 0.8500527816482009, 23.649983331004403, 0.0, u'0103'), 
    (0.02181070623592521, 0.15049387302788395, 1.2098398749067714, 1.6037412295275804, u'0102') 
    ] 

Хочу в каждой группе (группа = последнее значение в кортеже, например u'0102'):

  • Обобщить первый значение
  • Суммировать второе значение и разделить на сумму первого значения

Попытка:

import itertools 

Listoftuples=[ 
    (0.021892733407683305, 0.14887058717224647, 4.573173081530965, 0.04619366749021177, u'0102'), 
    (0.08416364174734663, 0.8500527816482009, 23.649983331004403, 0.0, u'0103'), 
    (0.02181070623592521, 0.15049387302788395, 1.2098398749067714, 1.6037412295275804, u'0102') 
    ] 

keyfunc=lambda t: (t[4]) 
Listoftuples.sort(key=keyfunc) 

for key,rows in itertools.groupby(Listoftuples, keyfunc): 
    sumOfFirstValue = sum(r[0] for r in rows) 
    sumOfSecondDividedBySumOfFirst= sum(r[1] for r in rows)/sumOfFirstValue 
    print key,sumOfFirstValue,sumOfSecondDividedBySumOfFirst 

Результаты:

0102 0.0437034396436 0.0 
0103 0.0841636417473 0.0 

Нулевые значения в прошлом. Как я могу это исправить?

+0

'rows' является итератором. Преобразуйте его в список перед выполнением операций над ним. –

ответ

5

Общая ошибка заключается в том, чтобы думать, что rows вернулся с groupby является конкретным списком. На самом деле это итератор и исчерпан при расчете sumOfFirstValue. Чтобы обойти проблема:

... 
for key,rows in itertools.groupby(Listoftuples, keyfunc): 
    rows = list(rows) 
    ... 
1

Простым решение без использования itertools:

groups = set(item[4] for item in Listoftuples) 
for g in groups: 
    sum_first_val = sum([item[0] for item in Listoftuples if item[4] == g]) 
    sum_second_val = sum([item[1] for item in Listoftuples if item[4] == g]) 
    print g, sum_first_val, sum_second_val/sum_first_val