gpt4 book ai didi

Python:产生并删除

转载 作者:太空狗 更新时间:2023-10-29 17:18:02 25 4
gpt4 key购买 nike

我如何从生成器中产生一个对象并立即忘记它,这样它就不会占用内存?

例如,在下面的函数中:

def grouper(iterable, chunksize):
"""
Return elements from the iterable in `chunksize`-ed lists. The last returned
element may be smaller (if length of collection is not divisible by `chunksize`).

>>> print list(grouper(xrange(10), 3))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
"""
i = iter(iterable)
while True:
chunk = list(itertools.islice(i, int(chunksize)))
if not chunk:
break
yield chunk

我不希望函数保留对 chunk 的引用在产生它之后,因为它不会被进一步使用并且只会消耗内存,即使所有外部引用都消失了。


编辑:使用来自 python.org 的标准 Python 2.5/2.6/2.7。


解决方案(@phihag 和@Owen 几乎同时提出):将结果包装在一个(小的)可变对象中并匿名返回 block ,只留下小容器:

def chunker(iterable, chunksize):
"""
Return elements from the iterable in `chunksize`-ed lists. The last returned
chunk may be smaller (if length of collection is not divisible by `chunksize`).

>>> print list(chunker(xrange(10), 3))
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
"""
i = iter(iterable)
while True:
wrapped_chunk = [list(itertools.islice(i, int(chunksize)))]
if not wrapped_chunk[0]:
break
yield wrapped_chunk.pop()

通过这种内存优化,您现在可以执行以下操作:

 for big_chunk in chunker(some_generator, chunksize=10000):
... process big_chunk
del big_chunk # big_chunk ready to be garbage-collected :-)
... do more stuff

最佳答案

yield chunk 之后,函数中不再使用变量值,因此一个好的解释器/垃圾收集器将已经释放 chunk 用于垃圾收集(注意:cpython 2.7 似乎这样做,带有默认 gc 的 pypy 1.6 会这样做)。因此,除了缺少 grouper 的第二个参数之外,您无需更改任何内容。

请注意,垃圾回收在 Python 中是不确定的。 null 垃圾收集器根本不收集空闲对象,是一个完全有效的垃圾收集器。来自Python manual :

Objects are never explicitly destroyed; however, when they become unreachable they may be garbage-collected. An implementation is allowed to postpone garbage collection or omit it altogether — it is a matter of implementation quality how garbage collection is implemented, as long as no objects are collected that are still reachable.

因此,如果不指定Python实现和垃圾收集器,就无法判断一个Python程序是否“占用内存”。给定特定的 Python 实现和垃圾收集器,您可以使用 gc模块到 test对象是否被释放。

话虽这么说,如果您真的不想从函数中获取任何引用(不一定意味着对象将被垃圾回收),请按以下步骤操作:

def grouper(iterable, chunksize):
i = iter(iterable)
while True:
tmpr = [list(itertools.islice(i, int(chunksize)))]
if not tmpr[0]:
break
yield tmpr.pop()

除了列表之外,您还可以使用任何其他具有删除和返回对象功能的数据结构,例如 Owen's wrapper .

关于Python:产生并删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7133179/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com