1
我正在学习Python的生成器,迭代器,iterables,我无法解释为什么以下不起作用。我想创建一个简单版本的zip函数作为练习。这是我做的:StopIteration在发电机
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
迭代器。这个元组就是屈服。
所以我期望在第一次执行时创建(并存储)对象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异常,我不明白为什么:每个迭代器仍然有一些值,因此next
都没有返回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)
这是怎么回事呢? 非常感谢
确定这确实是一个愚蠢的错误......我忘了补充一个周期,所以明确的功能后的第一个下一个死亡()。 谢谢! – edoedoedo
没问题。仅供参考,即使集合的大小不一样,“元组(iterable)中的下一个(可迭代的)”也将继续工作。使它成为'tuple([next(iterable)for iterable in iterable])'将触发StopIteration,所以你可以在最短的公共长度上停下来。 – algrebe
事实上,我看到如果我为了我在测试中:print(i)'我得到了一个无限循环。有什么不同? – edoedoedo