我尚未找到關於如何實際使用Python的itertools.groupby()
函數的可理解的解釋。 我想作的是這樣的: 函數
lxml
元素的子元素 我已經閱讀了文檔和示例 ,可是嘗試將它們應用到簡單的數字列表以外卻遇到了麻煩。 spa
那麼,如何使用itertools.groupby()
? 我應該使用另外一種技術嗎? 指向良好「前提」閱讀的指針也將受到讚揚。 指針
另外一個例子: code
for key, igroup in itertools.groupby(xrange(12), lambda x: x // 5): print key, list(igroup)
結果是 協程
0 [0, 1, 2, 3, 4] 1 [5, 6, 7, 8, 9] 2 [10, 11]
請注意,igroup是一個迭代器(文檔中稱爲子迭代器)。 xml
這對於分塊生成器頗有用: 對象
def chunker(items, chunk_size): '''Group items in chunks of chunk_size''' for _key, group in itertools.groupby(enumerate(items), lambda x: x[0] // chunk_size): yield (g[1] for g in group) with open('file.txt') as fobj: for chunk in chunker(fobj): process(chunk)
groupby的另外一個示例-不對鍵進行排序時。 在如下示例中,xx中的項目按yy中的值分組。 在這種狀況下,首先輸出一組零,而後輸出一組1,再輸出一組零。 排序
xx = range(10) yy = [0, 0, 0, 1, 1, 1, 0, 0, 0, 0] for group in itertools.groupby(iter(xx), lambda x: yy[x]): print group[0], list(group[1])
產生: 文檔
0 [0, 1, 2] 1 [3, 4, 5] 0 [6, 7, 8, 9]
@CaptSolo,我嘗試了您的示例,但沒有成功。 get
from itertools import groupby [(c,len(list(cs))) for c,cs in groupby('Pedro Manoel')]
輸出:
[('P', 1), ('e', 1), ('d', 1), ('r', 1), ('o', 1), (' ', 1), ('M', 1), ('a', 1), ('n', 1), ('o', 1), ('e', 1), ('l', 1)]
如您所見,有兩個o和兩個e,可是它們分紅不一樣的組。 從那時起,我意識到您須要對傳遞給groupby函數的列表進行排序。 所以,正確的用法是:
name = list('Pedro Manoel') name.sort() [(c,len(list(cs))) for c,cs in groupby(name)]
輸出:
[(' ', 1), ('M', 1), ('P', 1), ('a', 1), ('d', 1), ('e', 2), ('l', 1), ('n', 1), ('o', 2), ('r', 1)]
請記住,若是列表未排序,groupby函數將不起做用 !
我想再舉一個沒有排序的groupby沒法正常工做的例子。 改編自James Sulak的例子
from itertools import groupby things = [("vehicle", "bear"), ("animal", "duck"), ("animal", "cactus"), ("vehicle", "speed boat"), ("vehicle", "school bus")] for key, group in groupby(things, lambda x: x[0]): for thing in group: print "A %s is a %s." % (thing[1], key) print " "
輸出是
A bear is a vehicle. A duck is a animal. A cactus is a animal. A speed boat is a vehicle. A school bus is a vehicle.
有兩組帶有車輛的車輛,而一個能夠預期只有一組
警告:
語法列表(groupby(...))不能按您指望的方式工做。 彷佛破壞了內部迭代器對象,所以使用
for x in list(groupby(range(10))): print(list(x[1]))
將產生:
[] [] [] [] [] [] [] [] [] [9]
代替list(groupby(...)),嘗試[[k,list(g))for groupby(...)中的k,g,或者若是您常常使用該語法,
def groupbylist(*args, **kwargs): return [(k, list(g)) for k, g in groupby(*args, **kwargs)]
並訪問了groupby功能,同時避免了那些討厭的(對於小數據)迭代器。
如何使用Python的itertools.groupby()?
您可使用groupby對事物進行分組以進行迭代。 您爲groupby提供了一個可迭代的對象,以及一個可選的鍵函數/可調用對象,經過它能夠檢查從可迭代對象中出來的項,而後返回一個迭代器,該迭代器給出了可調用鍵和實際項的結果的二元組。另外一個可迭代的。 從幫助中:
groupby(iterable[, keyfunc]) -> create an iterator which returns (key, sub-iterator) grouped by each value of key(value).
這是groupby的示例,它使用協程對計數進行分組,它使用可調用鍵(在這種狀況下爲coroutine.send
)來吐出計數,不管迭代多少次,以及元素的分組子迭代器:
import itertools def grouper(iterable, n): def coroutine(n): yield # queue up coroutine for i in itertools.count(): for j in range(n): yield i groups = coroutine(n) next(groups) # queue up coroutine for c, objs in itertools.groupby(iterable, groups.send): yield c, list(objs) # or instead of materializing a list of objs, just: # return itertools.groupby(iterable, groups.send) list(grouper(range(10), 3))
版畫
[(0, [0, 1, 2]), (1, [3, 4, 5]), (2, [6, 7, 8]), (3, [9])]