2017-05-08 54 views
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) 

这是怎么回事呢? 非常感谢

回答

1

这里是一个有效的解决方案

def myzip(*collections): 

    iterables = tuple(iter(collection) for collection in collections) 

    while True: 
     try: 
      yield tuple([next(iterable) for iterable in iterables]) 
     except StopIteration: 
      # one of the iterables has no more left.     
      break 

test = myzip([1,2,3],(4,5,6),{7,8,9}) 

print(next(test)) 
print(next(test)) 
print(next(test)) 

该代码之间的区别和你的是,你的代码只得到一个结果。意思是,多次拨打下一个会给你一个StopIteration。

yield x想象为将x放入队列中,将next放入该队列中。当您尝试从空队列中弹出时,您会看到Stopiteration。你只能弹出和你一样多的弹出。

+0

确定这确实是一个愚蠢的错误......我忘了补充一个周期,所以明确的功能后的第一个下一个死亡()。 谢谢! – edoedoedo

+1

没问题。仅供参考,即使集合的大小不一样,“元组(iterable)中的下一个(可迭代的)”也将继续工作。使它成为'tuple([next(iterable)for iterable in iterable])'将触发StopIteration,所以你可以在最短的公共长度上停下来。 – algrebe

+0

事实上,我看到如果我为了我在测试中:print(i)'我得到了一个无限循环。有什么不同? – edoedoedo