2017-10-14 74 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 –

相关问题