繁体   English   中英

带有生成器和列表的python StopIteration

[英]python StopIteration with Generators and lists

按照让恩(Jean)对以下问题的回答: Python将列表中的字符串转换为数字 ,当运行以下最小代码时,我得到了StopIteration异常。

primesz2为空。

通过谷歌搜索,我认为我可能需要在回溯中绕线进行一会儿循环,但是我不确定该如何解决?

追溯:

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)]

列表推导本身不是生成器或迭代器。 当表达式端引发StopIteration异常时,它不会停止。 可迭代for ... in <iterable>遍历可以使用StopIteration向沟通for是迭代完成循环,但这并不延伸到结构的其余部分。

如果您需要从一个迭代器获取最多 b个元素,请使用itertools.islice()

primes = list(islice(z2, b))

迭代时最多需要b元素,如果z2中没有足够的元素,则更少。

您链接到的帖子的早期版本尝试通过为next()设置默认值,以用0填充结果,以防少于b元素。 我会使用itertools.repeat()itertools.chain()来实现这一点:

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

z2耗尽后chain(z2, repeat(0))部分将无限地添加0值。 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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM