“产量项”有什么优势? VS 返回 iter(items)?

发布于 2024-11-14 07:31:52 字数 501 浏览 4 评论 0原文

在下面的示例中,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(items) 是否比简单返回项目更好/更差?

在“Python Cookbook”中,Alex 表示显式 iter()“更灵活,但较少使用”,但是返回 iter(items) 与版本 2 中的 Yield 相比有何优缺点?

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

In the examples below, resp.results is an iterator.

Version1 :

items = []
for result in resp.results:
     item = process(result)
     items.append(item)
return iter(items)

Version 2:

for result in resp.results:
     yield process(result)

Is returning iter(items) in Version 1 any better/worse in terms of performance/memory savings than simply returning items?

In the "Python Cookbook," Alex says the explicit iter() is "more flexible but less often used," but what are the pros/cons of returning iter(items) vs yield as in Version 2?

Also, what are the best ways to unittest an iterator and/or yield? -- you can't do len(results) to check the size of the list?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一口甜 2024-11-21 07:31:52

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

results = [item for item in iterator]

或者正如评论中善意指出的,这是一个更简单的方法:

results = list(iterator)

It's easy to turn an iterator or generator back into a list if you need it:

results = [item for item in iterator]

Or as kindly pointed out in the comments, an even simpler method:

results = list(iterator)
兮子 2024-11-21 07:31:52

第一个导致计算和存储所有结果,而第二个是延迟加载,仅在请求时才计算结果。也就是说,一个将存储并创建包含 N 个项目的列表,而另一个将存储并创建 0 个项目,直到您开始迭代它们。

考虑这个问题的一个更好的方法是使用 ifilter (来自 itertools ),其中你做了很多事情与yield 相同,只是生成迭代器而不是生成器:

 ifilter(process, resp.results)

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

The first causes all the results to be calculated and stored while the second is a lazy load, whereby the results are calculated only when requested. That is, one will store and create a list of N items, while the other will store and create 0 items until you begin iterating through them.

A better way of thinking about this is using ifilter (from itertools) wherein you are doing much the same as yield except you're generating an iterator instead of a generator:

 ifilter(process, resp.results)

I've found that iterators are generally faster executing than generators in the 2.x series but I can not verify any cost savings in the 3.x series.

南风几经秋 2024-11-21 07:31:52

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

请参阅生成器中的一篇优秀文章 http://www.dabeaz.com/generators/Generators.pdf

When you are processing a very large list, then yield item is better since it does not consume much memory.

See an excellent article in generator http://www.dabeaz.com/generators/Generators.pdf

素手挽清风 2024-11-21 07:31:52

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

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

You can create infinite iterators, but not infinite lists:

def fibGen():
    f0, f1 = 0, 1
    while True:
        yield f0
        f0, f1 = f1, f0+f1
多情出卖 2024-11-21 07:31:52

前一个片段的优点和缺点是所有结果都是预先计算的。如果检索每个项目之间的时间很重要,那么这很有用,但如果可迭代对象是无限的或者空间是一个问题,则这将不起作用。

The pro and con of the former snippet is that all the results are calculated up front. This is useful if the time between retrieving each item is crucial, but won't do if the iterable is infinite or if space is a concern.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文