【发布时间】:2017-10-06 14:15:42
【问题描述】:
我正在学习 python 的生成器、迭代器、可迭代对象,但我无法解释为什么以下内容不起作用。作为练习,我想创建一个简单版本的函数 zip。这是我所做的:
def myzip(*collections):
iterables = tuple(iter(collection) for collection in collections)
yield tuple(next(iterable) for iterable in iterables)
test = myzip([1,2,3],(4,5,6),{7,8,9})
print(next(test))
print(next(test))
print(next(test))
我做的是:
- 我有
collections这是一些集合的元组 - 我创建了一个新元组
iterables,对于每个集合(可迭代),我使用iter获取迭代器 - 然后,我创建一个新元组,在每个可迭代对象上,我调用
next。然后这个元组就是 yield。
所以我希望在第一次执行时创建(并存储)对象iterables。然后在每次迭代(包括第一次)中,我对之前存储的每个迭代调用 next 并返回它。
但这是我得到的:
(1, 4, 8)
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-108-424963a58e58> in <module>()
8
9 print(next(test))
---> 10 print(next(test))
StopIteration:
所以我看到第一次迭代很好,结果是正确的。但是,第二次迭代引发了 StopIteration 异常,我不明白为什么:每个迭代仍然有一些值,所以 nexts 没有一个返回 StopIteration。事实上,这是可行的:
def myziptest(*collections):
iterables = tuple(iter(collection) for collection in collections)
for _ in range(3):
print(tuple(next(iterable) for iterable in iterables))
test = myziptest([1,2,3],(4,5,6),{7,8,9})
输出:
(1, 4, 8)
(2, 5, 9)
(3, 6, 7)
那么发生了什么? 非常感谢
【问题讨论】:
标签: python-3.x iterator generator