在使用生成器时,我需要澄清以下行为的内容。我担心我遗漏了一些基本的东西,所以欢迎任何建议。
(编辑)具体来说,我的问题涉及创建迭代器的迭代的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
一旦删除了iterable,迭代器引用的是什么?它是如何仍然能够拥有更小的mem足迹而且还能成功执行(我的印象是生成器只是指向现有数据,但如果它被删除,我必须耸耸肩?)
我错过了什么? (事情清楚。抱歉。我是自学成才)。提前致谢!
答案 0 :(得分:9)
我将此作为评论,但需要格式化才能明确:
>>> x = [1, 2, 3]
>>> y = [x]
>>> del x
>>> y
[[1, 2, 3]]
从本质上讲,它与您的示例相同:删除名称x
的绑定对y
的值完全没有影响,因为y
抓住了对象x
在绑定y
时已绑定。
以同样的方式,绑定到iterator
的生成器表达式捕获了当前iterable
iterator
当时绑定的绑定。
然而,在所有情况下,这并非完全直截了当。您可以read the PEP that introduced generator expressions了解详情。特别参见&#34;早期结合与晚期结合&#34;部分。
仅立即评估最外层的for-expression,其他表达式将延迟到生成器运行
你很幸运&#34;这里(但以一种非常常见的方式)因为iterable
位于&#34;最外面的for-expression&#34;您的生成器表达式。对象iterable
被绑定的原因是在您创建genexp时捕获的。