2017-10-14 46 views
1

以下是Jean對我的問題的回答:Python converting strings in a list to numbers,運行以下最小代碼時出現StopIteration異常。python帶有生成器和列表的StopIteration

primesz2是空的。

從谷歌搜索我想我可能需要一個while循環周圍的追溯線,但我不知道如何補救?

回溯:在CSV文件

File "factorise_v32.py", line 118, in factorise 
    primes=[next(z2) for _ in xrange(b)] 
StopIteration 

的樣本數據:

("2","3","5","7","11") 

最少的代碼:

import csv 

def factorise(N) 
    .... 
    z1=(int(x) for row in csv.reader(csvfile) for x in row) 
    .... 
    b=4 #b can be any positive integer 
    z2=(int(x) for row in csv.reader(csvfile) for x in row) 
    primes=[next(z2) for _ in xrange(b)] 
+1

'next()'引發異常,因爲'z2'已用盡。 'z2'中沒有'b'元素。 –

+0

@MartijnPieters不會處理'StopIteration'以終止理解? – schwobaseggl

+1

爲什麼不直接在* z2上迭代*?使它成爲列表理解,或者如果你想獲得有限數量的元素,可以使用'slice()'。 –

回答

2

列表理解是不是發電機或迭代器本身。當表達方引起StopIteration異常時,它不會停止。 for ... in <iterable>循環結束的迭代可以使用StopIterationfor循環進行通信,以完成迭代,但不會擴展到結構的其餘部分。

如果您需要在最b數量從一個迭代的元素得到,使用itertools.islice()

primes = list(islice(z2, b)) 

當遍歷這將需要長達b元素,或者更少,如果沒有足夠的元素在z2

您鏈接到試圖墊出在情況下,僅僅有不到b元素給予next()默認值0值結果後的早期版本。我已經使用itertools.repeat()itertools.chain()來實現這一目標:

primes = list(islice(chain(z2, repeat(0)), b)) 

chain(z2, repeat(0))部分將無休止地增加0值後z2耗盡。 islice()取自該序列的b元素。

演示:

>>> from itertools import chain, repeat, islice 
>>> z2 = iter([1, 2, 3]) 
>>> list(islice(z2, 5)) # up to 5 
[1, 2, 3] 
>>> z2 = iter([1, 2, 3]) # pad with zeros 
>>> list(islice(chain(z2, repeat(0)), 5)) 
[1, 2, 3, 0, 0] 

請注意,您不能從CSV連續文件兩次,沒有首先倒帶文件對象讀取。您的代碼在兩個位置使用csv.reader(csvfile),但csvfile文件對象不會回到起點。在嘗試再次讀取之前添加csvfile.seek(0)

+0

@ Jean-FrançoisFabre:調整了措辭。 –

+0

和往常一樣完美:)你最近對自己進行了「我不是pybot」嗎? –

+1

@Jan ssssh!如果他發現他真的是他的節目,他的節目可能會中斷! :p –

相關問題