2013-03-16 35 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:

所以,我怎樣才能創建我的列表,而不對key進行多重處理,groupby(rows,lambda k:k [0])中的位置:?

我希望這很清楚,但很高興能夠根據需要提供更多信息。

+0

注意,而不是'lambda'功能,你應該使用['operator.itemgetter(0)'(http://docs.python.org/3.3/library/operator.html#operator。 itemgetter)。 (如果你使用gnibbler的答案,那麼你可以將itemgetter存儲到一個變量中,並使用它兩次以保存兩次創建相同的東西)。 – 2013-03-16 13:57:13

+0

您可以使用['itertools.tee'](http://docs.python.org/2/library/itertools.html?highlight=itertools#itertools.tee)從單個迭代中創建2個獨立的迭代器。 – nymk 2013-03-16 14:12:57

回答

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 2013-03-16 15:56:57