Python迭代器(生成器)删除源码,仍然有效.到底是怎么回事?

mat*_*orm 2 python generator

我需要澄清一下使用生成器时出现以下行为的情况.我担心我遗漏了一些基本的东西,所以欢迎任何建议.

(编辑)具体来说,我的问题涉及del创建迭代器的迭代.

我的最终用例是我正在迭代一个非常庞大的语料库进行文本处理.它不是那么大,以至于无法保存在内存中,但足够大,以至于无法在内存中训练后续模型.

所以,在我的调查中,我尝试了以下内容,我很困惑这是如何工作的.

>>> iterable = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
>>> iterable.__sizeof__()
    160
>>> iterator = (x+1 for x in iterable)
>>> iterator
<generator object <genexpr> at 0x1019f8570>
>>> iterator.__sizeof__()
64
>>> del iterable
>>> for i in iterator:
...     print(i)
...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Run Code Online (Sandbox Code Playgroud)

一旦我删除了iterable,迭代器引用的是什么?它是如何仍然能够拥有更小的mem足迹但也成功执行(我的印象是生成器只是指向现有数据,但如果它被删除,我必须耸耸肩?)

我错过了什么?(事情清楚.抱歉.我是自学成才).提前致谢!

Tim*_*ers 9

我将此作为评论,但需要格式化才能明确:

>>> x = [1, 2, 3]
>>> y = [x]
>>> del x
>>> y
[[1, 2, 3]]
Run Code Online (Sandbox Code Playgroud)

从内心来说,它与你的例子是一样的:删除名称的绑定对于x值的任何影响都没有y,因为y捕获的对象x 绑定时y被绑定.

以相同的方式,发电机表达你结合到iterator捕获的当时的结合iterable在当时iterator被绑定.

但是,在所有情况下,这并非完全直截了当.您可以阅读引入生成器表达式的PEP以获取详细信息.特别参见"早期结合与晚期结合"部分.

仅立即计算最外层的for-expression,其他表达式将延迟直到生成器运行

你在这里"幸运"(但是以一种非常普遍的方式)因为iterable你的生成器表达式的"最外层的表达式".这就是在创建genexp iterable捕获对象的原因.