【问题标题】:What are the advantages of "yield item" vs return iter(items)?“yield item”和 return other(items) 的优势是什么?
【发布时间】:2011-09-08 01:33:24
【问题描述】:

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

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

【问题讨论】:

  • 嗯。版本 2 更短,并且不创建中间列表对象。你为什么不简单地每次都使用它?为什么你认为这些是“模棱两可的”或“等效的”?仅仅返回一个迭代器并不是真正的问题,是吗?
  • 这里对yield关键字有很好的解释:stackoverflow.com/questions/231767/…
  • 那么你什么时候使用 iter() -- 根据 (stackoverflow.com/questions/231767/…) -- 'for' 循环不会自动对所有列表执行 'iter(mylist)' 吗?跨度>
  • S.Lott - AFAIK 你不能重用生成器,所以迭代器更灵活。
  • @James 为什么不创建另一个生成器?我觉得没那么贵。

标签: python unit-testing iterator yield


【解决方案1】:

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

results = [item for item in iterator]

或者正如 cmets 中所指出的,一种更简单的方法:

results = list(iterator)

【讨论】:

  • 为什么不只是list(iterator)
  • 谢谢。这将有助于单元测试迭代器——单元测试 yield 语句的任何技巧?
  • @isakkarlsson,为什么不呢? Python 之禅的一部分应该是任何事情的“一种明显的方式”,但我总是被异常绊倒。
  • @James,同样适用于迭代器或生成器。事实上,我一直混淆这两者,因为它们非常相似。
【解决方案2】:

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

考虑这一点的更好方法是使用 ifilter(来自 itertools),其中您所做的与 yield 几乎相同,只是您生成的是迭代器而不是生成器:

 ifilter(process, resp.results)

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        前一个sn-p的优点的缺点是所有的结果都是预先计算好的。如果检索每个项目之间的时间很关键,这很有用,但如果迭代是无限的或者如果空间是一个问题,则不会这样做。

        【讨论】:

          猜你喜欢
          • 2010-11-08
          • 1970-01-01
          • 2017-01-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-30
          • 2014-08-03
          相关资源
          最近更新 更多