2010-08-09 59 views
7

爲了說明這一點,我開始用2元組的列表:如何在迭代器的元素中使用itertools.groupby?

import itertools 
import operator 

raw = [(1, "one"), 
     (2, "two"), 
     (1, "one"), 
     (3, "three"), 
     (2, "two")] 

for key, grp in itertools.groupby(raw, key=lambda item: item[0]): 
    print key, list(grp).pop()[1] 

產量:

1 one 
2 two 
1 one 
3 three 
2 two 

在試圖調查爲何:

for key, grp in itertools.groupby(raw, key=lambda item: item[0]): 
    print key, list(grp) 

# ---- OUTPUT ---- 
1 [(1, 'one')] 
2 [(2, 'two')] 
1 [(1, 'one')] 
3 [(3, 'three')] 
2 [(2, 'two')] 

即使這會給我相同的輸出:

for key, grp in itertools.groupby(raw, key=operator.itemgetter(0)): 
    print key, list(grp) 

我想要得到的東西,如:

1 one, one 
2 two, two 
3 three 

我想這是因爲關鍵是列表內部的元組內的時候,其實元組被搬來搬去爲一體。有沒有辦法達到我想要的結果?也許groupby()不適合這個任務?

回答

9

groupby集羣連續具有相同鍵的可迭代元素。 要產生你想要的輸出,你必須首先排序raw

for key, grp in itertools.groupby(sorted(raw), key=operator.itemgetter(0)): 
    print key, map(operator.itemgetter(1), grp) 

# 1 ['one', 'one'] 
# 2 ['two', 'two'] 
# 3 ['three'] 
+0

我想'grp'是'itertool._grouper'對象。我可以用'_grouper'做些什麼'builtin'動作?我看到你把它當作一個'iterable'來對待?整齊! – Kit 2010-08-09 13:52:20

+0

@Kit:我認爲關於'grp'的主要有用的事實是它是一個'iterable'。在你提到它之前,我不知道它是一個'itertools._grouper'對象。這似乎是鴨式打字便利的一個很好的例子。我們不需要知道'grp'的類型,只需要它實現'iterable'接口。 – unutbu 2010-08-09 18:18:37

+0

+1''itemgetter' – Krastanov 2013-03-30 14:35:48

2

docs

GROUPBY的操作()類似於 UNIX中的uniq的過濾器。它 生成一箇中斷或新組每 時間鍵功能 的值更改(這就是爲什麼它通常是 需要使用相同的鍵功能排序數據 )。 行爲不同於SQL的GROUP BY ,它聚合公共元素 ,而不管它們的輸入順序如何。

既然你是按字典反正排序元組,你可以叫sorted

for key, grp in itertools.groupby(sorted(raw), key = operator.itemgetter(0)): 
    print(key, list(map(operator.itemgetter(1), list(grp)))) 
+6

刪除括號內的空格會讓我感到溫暖和模糊內部;) – 2010-08-09 14:36:47

+1

我是一個信徒在\ t \ n \ n,空白的主。他告訴我PEP-8是錯誤的,而且這個世界需要更多的空白! – katrielalex 2010-08-09 15:00:01

6

我認爲一個更清潔的方式來獲得您想要的結果是這樣的。

>>> from collections import defaultdict 
>>> d=defaultdict(list) 
>>> for k,v in raw: 
... d[k].append(v) 
... 
>>> for k,v in sorted(d.items()): 
... print k, v 
... 
1 ['one', 'one'] 
2 ['two', 'two'] 
3 ['three'] 

建設d爲O(n),現在sorted()只是在唯一的密鑰,而不是整個數據集