Python 为什么'zip'似乎要使用'groupby'可伸缩表?
因此,使用Python 为什么'zip'似乎要使用'groupby'可伸缩表?,python,python-3.x,itertools,Python,Python 3.x,Itertools,因此,使用itertools.groupby()拆分列表相当简单 >>> import itertools as it >>> iterable = it.groupby([1, 2, 3, 4, 5, 2, 3, 4, 2], lambda p: p==2) >>> for x, y in iterable: ... print(x, list(y)) ... next(iterable) False [1] False [
itertools.groupby()
拆分列表相当简单
>>> import itertools as it
>>> iterable = it.groupby([1, 2, 3, 4, 5, 2, 3, 4, 2], lambda p: p==2)
>>> for x, y in iterable:
... print(x, list(y))
... next(iterable)
False [1]
False [3, 4, 5]
False [3, 4]
一切正常。但是,使用一种常见的python习惯用法zip
多次启动迭代器,一次执行2,似乎会破坏一切
>>> iterable = it.groupby([1, 2, 3, 4, 5, 2, 3, 4, 2], lambda p: p==2)
>>> for (x, y), _ in zip(iterable, iterable):
... print(x, list(y))
False []
False []
False []
添加一个print(y)
会显示预期的嵌套iterable
,但是我显然没有理解为什么grouper
对象是空的。有人能解释一下吗
如果我有一个不均匀的列表并使用itertools.zip\u longest
,我会得到一个更奇怪的结果:
>>> iterable = it.groupby([1, 2, 3, 4, 5, 2, 3, 4], lambda p: p==2)
>>> for (x, y), _ in it.zip_longest(iterable, iterable, fillvalue=None):
... print(x, list(y))
False []
False []
False [4]
更新:简单的修复方法是使用itertools.islice()
:
groupby
文档警告您
返回的组本身是一个迭代器,它与groupby()共享基础iterable。因为源是共享的,所以当groupby()对象处于高级状态时,上一个组不再可见
当您的zip
生成((键,组),(键,组))
对时,它将groupby
迭代器向前推进,使第一个组无法使用。在前进之前,您需要具体化团队:
iterable = ((key, list(group)) for (key, group) in it.groupby([1, 2, 3, 4, 5, 2, 3, 4, 2], lambda p: p==2))
for (x, y), _ in zip(iterable, iterable):
print(x, y)
因为一旦进入
itertools.groupby
中的下一项,它就会丢弃以前遇到的任何\u grouper
-生成器
它们将显示最新的项目:
>>> iterable = it.groupby([1, 2, 3, 4, 5, 2, 3, 4, 2], lambda p: p==2)
>>> for (x, y), (x2, y2) in zip(iterable, iterable):
... print(x2, list(y2))
True [2]
True [2]
True [2]
包含有关此行为的警告:
返回的组本身是一个迭代器,它与groupby()共享基础iterable。因为源是共享的,所以当groupby()对象处于高级状态时,上一个组将不再可见。因此,如果以后需要该数据,则应将其存储为列表
因此,通过使用zip中的
(x,y),uu(iterable,iterable)
您实际上将迭代器提升了2(即使最新的结果被转储到u
),而第一个迭代器(您的x,y
)不再可用 谢谢,有道理。如果grouper在最后一次迭代中没有被提升,那么最后一个结果是[4]
而不是[3,4]
,这是因为它是高级的。@AChampion:但是它是高级的,因为groupby
需要提升底层迭代器以确定没有最终的组。(之所以使用[4]
而不是[]
,是因为提供的链接中提到了实现细节。)
>>> iterable = it.groupby([1, 2, 3, 4, 5, 2, 3, 4, 2], lambda p: p==2)
>>> for (x, y), (x2, y2) in zip(iterable, iterable):
... print(x2, list(y2))
True [2]
True [2]
True [2]