2017-05-08 104 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