2016-09-25 115 views
2
from collections import defaultdict 
import itertools 

items = [(0, 0), (0, 1), (1, 0), (1, 1)] 

keyfunc = lambda x: x[0] 

# Grouping yourself 
item_map = defaultdict(list) 
for item in items: 
    item_map[keyfunc(item)].append(item) 

# Using itertools.groupby 
item_map = {} 
for key, group in itertools.groupby(items, keyfunc): 
    item_map[key] = [i for i in group] 

itertools.groupby有什麼了不起的,我應該使用它而不是自己做?它能以更少的時間複雜度執行分組嗎?或者,我是否用我的用例缺少了這一點,groupby應該用於其他情況?爲什麼使用itertools.groupby而不是自己做?


另一個海報提到itertools.groupby將返回不同的結果,如果進行分組的項目不是由鍵排序(或者更確切地說,只是按鍵是連續彼此)。

例如,items = [(0, 0), (1, 1), (0, 2)],如果我們不排序的關鍵,itertools.groupby回報

{0: [(0, 2)], 1: [(1, 1)]} 

而我實現返回

{0: [(0, 0), (0, 2)], 1: [(1, 1)]} 

除非我誤解了點,它會似乎DIY方法更好,因爲它不需要對數據進行排序。

這裏是documentation

請返回從迭代連續按鍵和組迭代器。關鍵是計算每個元素的關鍵值的函數。如果沒有指定或者是None,那麼key默認爲一個標識函數,並且返回該元素不變。一般而言,迭代器需要在同一個按鍵函數上進行排序

回答

2

通常,使用迭代器的要點是避免將整個數據集保留在內存中。在你的例子中,這並不重要,因爲:

  • 輸入已經全部在內存中。
  • 你只是傾倒一切到dict,所以輸出也都在內存中。

或者,我錯過了我的用例,並且groupby應該用於其他情況?

我認爲這是一個準確的評估。

假設items是一個迭代器(例如,讓我們說這是從標準輸入讀取線)和輸出比在內存中的數據結構以外的東西(如標準輸出):

for key, group in itertools.groupby(items, keyfunc): 
    print("{}: {}".format(key, str([i for i in group]))) 

現在會少你自己做那件事很簡單。