我尚未找到关于如何实际使用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])]