因此,使用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]
按预期工作。但是使用zip
多次迭代迭代器的常见python习惯用法一次两步,似乎会破坏事物。
>>> 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)
会显示预期的嵌套可迭代<itertools._grouper object at 0xXXXXXXXX>
,但我显然遗漏了grouper
对象为何为空的内容。任何人都能解释一下吗?
如果我的列表不均匀并且使用itertools.zip_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()
:
>>> iterable = it.groupby([1, 2, 3, 4, 5, 2, 3, 4, 2], lambda p: p==2)
>>> for x, y in it.islice(iterable, None, None, 2):
... print(x, list(y))
False [1]
False [3, 4, 5]
False [3, 4]
答案 0 :(得分:6)
groupby
文档警告您
返回的组本身就是一个迭代器,它与groupby()共享底层的iterable。由于源是共享的,因此当groupby()对象前进时,前一个组不再可见。
当zip
生成((key, group), (key, group))
对时,它会使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)
答案 1 :(得分:2)
因为只要您到达itertools.groupby
中的下一个项目,就会丢弃之前遇到的所有_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]
documentation包含有关此行为的警告:
返回的组本身就是一个迭代器,它与groupby()共享底层的iterable。由于源是共享的,因此当groupby()对象处于高级时,前一个组将不再可见。因此,如果稍后需要该数据,则应将其存储为列表。
因此,通过使用(x, y), _ in zip(iterable, iterable)
,你实际上将迭代器提高了2(即使最新结果被转储到_
中),第一个(你的x, y
)也不再可用了!