Python “的优点是什么?”;“收益项目”;返回国际热核实验堆(项目)?

Python “的优点是什么?”;“收益项目”;返回国际热核实验堆(项目)?,python,unit-testing,iterator,yield,Python,Unit Testing,Iterator,Yield,在下面的示例中,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(项目)是否比单纯退回项目更好/更差 在“Pyt

在下面的示例中,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食谱”中,Alex说显式iter()更灵活,但使用频率更低,但是在版本2中返回iter(items)和yield的优缺点是什么


另外,单元测试迭代器和/或产生迭代器的最佳方法是什么你不能用len(results)来检查列表的大小吗?

前一个代码段的正反两方面是,所有结果都是预先计算出来的。如果检索每个项目之间的时间非常关键,但如果iterable是无限的或空间是一个问题,则此选项非常有用。

当您处理一个非常大的列表时,则
yield item
更好,因为它不会消耗太多内存


请参阅generator中的一篇优秀文章,第一篇文章导致计算和存储所有结果,而第二篇文章是延迟加载,因此仅当请求时才计算结果。也就是说,一个将存储并创建一个包含N个项目的列表,而另一个将存储并创建0个项目,直到您开始遍历它们为止

考虑这一点的更好方法是使用ifilter(from),其中除了生成迭代器而不是生成器之外,您的操作与yield基本相同:

 ifilter(process, resp.results)

我发现迭代器的执行速度通常比2.x系列中的生成器快,但我无法验证3.x系列中的任何成本节约。

如果需要,可以很容易地将迭代器或生成器转换回列表:

results = [item for item in iterator]
或者,正如评论中善意指出的,更简单的方法是:

results = list(iterator)

您可以创建无限迭代器,但不能创建无限列表:

def fibGen():
    f0, f1 = 0, 1
    while True:
        yield f0
        f0, f1 = f1, f0+f1

嗯。版本2较短,不创建中间列表对象。你为什么不每次都用它呢?为什么你认为这些是“模棱两可”或“同等的”?仅仅返回一个迭代器并不是真正的问题,对吗?这里有一个关于yield关键字的很好的解释:那么什么时候你会使用iter()--per()--“for”循环不会自动执行iter(mylist)“对所有列表?S.Lott-AFAIK您不能重用生成器,因此迭代器更灵活。@James为什么不创建另一个生成器?我觉得没那么贵。为什么不干脆
list(迭代器)
?谢谢。这将有助于单元测试迭代器——单元测试产生语句的技巧吗?@Isakkarsson,为什么不呢?Python禅宗的一部分被认为是任何东西的“一种显而易见的方式”,但我总是被异常绊倒。@James,迭代器或生成器也是如此。事实上,我一直在混淆这两者,因为它们太相似了。