在Jean回答我的问题:Python converting strings in a list to numbers后,运行以下最小代码时出现StopIteration
异常。
primes
和z2
为空。
从谷歌搜索我觉得我可能需要在回溯线上绕一条线循环,但我不确定如何补救?
回溯:
File "factorise_v32.py", line 118, in factorise
primes=[next(z2) for _ in xrange(b)]
StopIteration
CSV文件中的示例数据:
("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)]
答案 0 :(得分:2)
列表推导不是生成器或迭代器本身。当表达式端引发StopIteration
异常时,它不会停止。 for ... in <iterable>
循环的 iterable 可以使用StopIteration
与迭代完成的for
循环进行通信,但不会扩展到其余部分构造
如果您需要从迭代器中获取最多 b
个元素,请使用itertools.islice()
:
primes = list(islice(z2, b))
迭代时最多需要b
个元素,如果z2
中没有足够的元素,则会更少。
您链接到的帖子的早期版本尝试填充结果0
值,以防少于b
个元素通过提供next()
一个默认值。我已经使用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)
。