【问题标题】:How do Python Generators Save Memory [duplicate]Python生成器如何节省内存[重复]
【发布时间】:2015-01-08 18:02:15
【问题描述】:

我理解生成器返回一个“保存状态”的可迭代对象并且不会立即计算所有内容的一般想法,而是在每次调用 next 时进行计算。这是如何运作的?例如[x for x in range(10) if x%2==0](x for x in range(10) if x%2==0)。在列表理解中,所有内容都会立即计算并存储在内存中。

在生成器中,不会生成整个列表,而是生成一个可迭代的生成器对象,每次调用 next 时都会进行计算。但是这个生成器必须以某种方式知道它的“边界”,对吧?生成器如何知道,如果它不在后台执行所有计算,从哪里开始它停止的地方?我认为它必须知道列表理解中的每一步,最终如果你最终循环遍历整个生成器直到 StopIteration 被击中,我认为你使用的内存量大致相同。

【问题讨论】:

  • 嘿,@thefourtheye,事实上,我正准备将相同的信息重新散列成稍微不同的形式。但另一个答案确实也包含足够的信息来回答这个问题。
  • range 将返回一个列表(至少在 python 2x 中)......基本上完全消除了生成器的任何好处......
  • @JoranBeasley:让我们假设 OP 正在使用 Python 3.x。 :-)
  • 是的,很公平:P

标签: python generator


【解决方案1】:

但是这个生成器必须以某种方式知道它的“边界”,对吧?

不,它没有!它只是继续卡车运输,直到达到StopIteration。它一次只处理内存中的一个元素,然后将其丢弃。

【讨论】:

  • 我将查看上面建议的重复项(我之前确实尝试过搜索),但这基本上是我不理解的。要一次只处理一个项目,它必须知道它所在的可迭代对象的顺序在哪里,那么它如何知道它是否丢弃了每个先前的元素?换句话说,它怎么知道下一个已经被称为“x”很多次,并且它现在需要执行“第三次”计算,例如,如果它没有保持计算的累积计数(因此我认为消除命中 StopIteration 时的内存收益)
  • 尝试阅读this article。每次你想要一个元素时,生成器都会简单地继续调用next,直到它们遇到StopIteration。他们不知道,也不可能知道StopIteration 会在哪里出现,直到他们到达那里。
猜你喜欢
  • 1970-01-01
  • 2016-08-29
  • 1970-01-01
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 2010-11-05
  • 1970-01-01
相关资源
最近更新 更多