在下面的示例中,resp.results是一个迭代器。
版本1:
items = []
for result in resp.results:
item = process(result)
items.append(item)
return iter(items)
第2版:
for result in resp.results:
yield process(result)
返回版本1中的iter(项目)在性能/内存节省方面是否比简单返回项目更好/更差?
在“Python Cookbook”中,Alex表示明确的iter()“更灵活,但不经常使用”,但在版本2中返回iter(items)与yield的优缺点是什么?
此外,对迭代器和/或产量进行单元测试的最佳方法是什么? - 你不能做len(结果)检查列表的大小?
答案 0 :(得分:4)
第一个导致计算和存储所有结果,而第二个是延迟加载,从而仅在请求时计算结果。也就是说,一个将存储并创建N个项目的列表,而另一个将存储并创建0个项目,直到您开始迭代它们。
更好的思考方法是使用ifilter(来自itertools),其中除了生成迭代器而不是生成器之外,你做的与yield相同:
ifilter(process, resp.results)
我发现迭代器的执行速度通常比2.x系列中的生成器快,但我无法验证3.x系列中的任何成本节省。
答案 1 :(得分:4)
如果需要,可以很容易地将迭代器或生成器重新打开到列表中:
results = [item for item in iterator]
或者正如评论中所指出的那样,一种更简单的方法:
results = list(iterator)
答案 2 :(得分:3)
当您处理一个非常大的列表时,yield item
更好,因为它不会消耗太多内存。
答案 3 :(得分:2)
您可以创建无限迭代器,但不能创建无限列表:
def fibGen():
f0, f1 = 0, 1
while True:
yield f0
f0, f1 = f1, f0+f1
答案 4 :(得分:1)
前代码段的pro 和 con是所有结果都是预先计算出来的。如果检索每个项目之间的时间至关重要,但如果可迭代是无限的,或者如果空间是一个问题,那么这将是有用的。