如果一个Python迭代器返回可迭代对象,如何将这些对象链成一个大迭代器?

4 投票
2 回答
1592 浏览
提问于 2025-04-16 07:45

我这里给一个简单的例子。假设我在Python中有一个迭代器,这个迭代器每次返回的对象本身也是可以迭代的。我想把这个迭代器返回的所有对象连成一个很长的迭代器。有没有什么标准的方法可以做到这一点呢?

下面是一个虚构的例子。

x = iter([ xrange(0,5), xrange(5,10)])

x 是一个返回迭代器的迭代器,我想把 x 返回的所有迭代器连成一个大的迭代器。在这个例子中,进行这样的操作后,结果应该等同于 xrange(0,10),并且应该是懒加载的。

2 个回答

3

这是传统的方法:

Python 2.2.3 (#42, May 30 2003, 18:12:08) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from __future__ import generators
>>> def mychain(iterables):
...     for it in iterables:
...         for item in it:
...             yield item
...
>>> x = iter([ xrange(0,5), xrange(5,10)])
>>> a = mychain(x)
>>> list(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>

我不太明白在这种情况下使用 iter() 的目的或好处是什么:

>>> x = [xrange(0,5), xrange(5,10)]
>>> a = mychain(x)
>>> list(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
10

你可以使用 itertools.chain.from_iterable 这个功能。

>>> import itertools
>>> x = iter([ xrange(0,5), xrange(5,10)])
>>> a = itertools.chain.from_iterable(x)
>>> list(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

如果你的版本没有这个功能(显然它是在2.6版本中新增的),你可以手动实现这个功能:

>>> x = iter([ xrange(0,5), xrange(5,10)])
>>> a = (i for subiter in x for i in subiter)
>>> list(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

撰写回答