itertools.groupby:迭代遍历组pairwise
如何迭代groupby
成对结果?我试过不是很工作:itertools.groupby:迭代遍历组pairwise
from itertools import groupby,izip
groups = groupby([(1,2,3),(1,2),(1,2),(3,4,5),(3,4)],key=len)
def grouped(iterable, n):
return izip(*[iterable]*n)
for g, gg in grouped(groups,2):
print list(g[1]), list(gg[1])
输出我得到:
[] [(1, 2), (1, 2)]
[] [(3, 4)]
输出我想有:
[(1, 2, 3)] [(1, 2), (1, 2)]
[(3, 4, 5)] [(3, 4)]
import itertools as IT
groups = IT.groupby([(1,2,3),(1,2),(1,2),(3,4,5),(3,4)], key=len)
groups = (list(group) for key, group in groups)
def grouped(iterable, n):
return IT.izip(*[iterable]*n)
for p1, p2 in grouped(groups, 2):
print p1, p2
产生
[(1, 2, 3)] [(1, 2), (1, 2)]
[(3, 4, 5)] [(3, 4)]
您发布的代码非常有趣。它有一个普通的问题,还有一个微妙的问题。
一个普通的问题是itertools.groupby返回一个迭代器,它在每次迭代时输出一个键和一个组。 既然你感兴趣的只是群体,没有钥匙,你需要像
groups = (group for key, group in groups)
微妙的问题更难以解释 - 我真的不知道我完全理解。这是我的猜测:由groupby
返回的迭代器已经把它的输入,
[(1,2,3),(1,2),(1,2),(3,4,5),(3,4)]
成一个迭代器。 groupby迭代器包装在底层数据迭代器中,类似于csv.reader
如何包装底层文件对象迭代器。你只能通过这个迭代器一次,只有一次通过。 itertools.izip函数在配对groups
中的项目过程中会导致迭代器从第一项前进到第二项。由于您只能通过迭代器一次,所以第一项已被使用,所以当您拨打list(g[1])
时,它是空的。
一个
不那么满意
修复这个问题是迭代器转换成groups
到列表:
groups = (list(group) for key, group in groups)
所以itertools.izip
不会过早食用。编辑:第二个想法,这个修复不是很糟糕。 groups
仍然是一个迭代器,并且仅在消耗时才将group
转换为列表。
当您尝试查看groupby
中的第二个键时,您迫使其将迭代到源迭代器中。由于通常无法存储来自第一组的物品,因此它们被简单地丢弃。
因此,现在我们理解为什么我们需要确保我们已经存储了第一组中的项目,然后再尝试查看第二组的项目(或项目)。
有些人肯定会讨厌这一点,但
>>> groups = groupby([(1, 2, 3), (1, 2), (1, 2), (3, 4, 5), (3, 4)], key=len)
>>> for i, j in ((list(i[1]), list(next(groups)[1])) for i in groups):
... print i, j
...
[(1, 2, 3)] [(1, 2), (1, 2)]
[(3, 4, 5)] [(3, 4)]
振聋发聩这是非常邪恶的:) – root 2013-02-14 13:46:48
你的编辑和往常一样:) – root 2013-02-14 13:59:09