2014-03-28 54 views
0

首先,我對這個問題的描述很不好。我找不到更好的。早期通過Python實現groupby的itertools.groupby的怪異

我發現將列表應用於itertools.groupby結果會破壞結果。見代碼:

import itertools 
import operator 

log = '''\ 
hello world 
hello there 
hi guys 
hi girls'''.split('\n') 

data = [line.split() for line in log] 

grouped = list(itertools.groupby(data, operator.itemgetter(0))) 

for key, group in grouped: 
    print key, group, list(group) 

print '-'*80 

grouped = itertools.groupby(data, operator.itemgetter(0)) 

for key, group in grouped: 
    print key, group, list(group) 

結果是:

hello <itertools._grouper object at 0x01A86050> [] 
hi <itertools._grouper object at 0x01A86070> [['hi', 'girls']] 
-------------------------------------------------------------------------------- 
<itertools.groupby object at 0x01A824E0> 
hello <itertools._grouper object at 0x01A860B0> [['hello', 'world'], ['hello', 'there']] 
hi <itertools._grouper object at 0x01A7DFF0> [['hi', 'guys'], ['hi', 'girls']] 

也許這是關係到GROUPBY功能的內部工作。不過今天讓我感到吃驚。

回答

4

這是documented

返回的基團本身是與groupby()共享迭代底層的迭代器。由於源是共享的,因此當groupby()對象進階時,先前的組不再可見。

當你做list(groupby(...)),你一直推進groupby對象到最後,這會失去除最後一組以外的所有組。如果您需要保存組,請按照文檔中的說明進行操作,並在迭代groupby對象時保存每個組。

1

文檔中的例子並不像你一樣:在打開迭代器組的按鍵的元組和列表的列表

list((key, list(group)) for key, group in itertools.groupby(...)) 

[(key,[group])]如果這就是希望。

+0

如果你想這樣做,不需要使用'list',直接使用列表理解:'[(key,list(group))for key,itertools.groupby(...)]' – BrenBarn

+0

@BrenBarn在Python 2和Python 3上,Python 2和Python 2都沒有相同的行爲,但它泄漏了生成器表達式所沒有的變量。這在Python 3中得到了修復,但是這樣做會減少在list()上使用'[]'的速度。而且也不能簡單地用'dict'代替'list'並取而代之'{key:[group]}'。 –