2013-03-16 2 views
1

У меня есть записи, возвращаемые из базы данных, которая выглядит следующим образом:Python itertools.groupby несколько значений

region  month_taken   total_att num_classes 
Colorado 2013-01-01 00:00:00.000 78485 4648 
Colorado 2013-02-01 00:00:00.000 71769 4162 
Midwest  2013-01-01 00:00:00.000 110508 7101 
Midwest  2013-02-01 00:00:00.000 103545 6410 

Я пытаюсь получить их в списки, как так:

Total_att:

[{"data": [78485, 71769], "name": "Colorado"}, {"data": [110508, 103545], "name": "Midwest"}] 

num_classes:

[{"data": [4648, 4162], "name": "Colorado"}, {"data": [7101, 6410], "name": "Midwest"}] 

Я обнаружил itertools.groupby, который делает то, что я хочу, но мне трудно делать это с более чем одним списком значений (из-за отсутствия лучшего термина).

totalResults = []    
for key, location in groupby(rows, lambda k: k[0]): 
    totalRow = dict() 
    totalRow['name'] = key 
    totalRow['data'] = [x[2] for x in location] 
    totalResults.append(totalRow) 

Великий, который получает мне мой список total_att, но потом я весь цикл дополнительного GroupBy, чтобы создать список «num_classes», который кажется смешным. Я видел это в документации, но, честно говоря, я не совсем уверен, что это значит, или как справиться с моей проблемой, если я преобразовал его в список:

The returned group is itself an iterator that shares the underlying iterable with groupby(). Because the source is shared, when the groupby() object is advanced, the previous group is no longer visible. So, if that data is needed later, it should be stored as a list:

Итак, как я могу создать свои списки без делать несколько для ключа, местоположение в groupby (rows, lambda k: k [0]) :?

Я надеюсь, что это понятно, но я рад предоставить дополнительную информацию по мере необходимости.

+0

Обратите внимание, что вместо 'функции lambda', вы должны использовать [' operator.itemgetter (0) '] (http://docs.python.org/3.3/library/operator.html#operator. itemgetter). (Если вы используете ответ gnibbler, то вы можете сохранить itemgetter в переменную и использовать его дважды, чтобы сохранить создание одной и той же вещи дважды). –

+0

Вы можете использовать ['itertools.tee'] (http://docs.python.org/2/library/itertools.html?highlight=itertools#itertools.tee), чтобы создать 2 независимых итератора из одного итерабельного. – nymk

ответ

2
totalResults = [] 
totalClasses = []   
for key, location in groupby(rows, lambda k: k[0]): 
    location = list(location) 
    totalResults.append(dict(name=key, data=[x[2] for x in location])) 
    totalClasses.append(dict(name=key, data=[x[3] for x in location])) 
+0

Пятно на, спасибо. – duffn

Смежные вопросы