gpt4 book ai didi

python - 如何在 python 中截断列表?分配一个新的 list() 会导致内存泄漏吗?

转载 作者:太空宇宙 更新时间:2023-11-04 07:42:21 24 4
gpt4 key购买 nike

假设我在 python 中有一个相当大的列表 my_list,我想截断它。我可以通过删除它或将新列表分配给 my_list 来实现它。什么是更好的方法?

my_list = range(1, 10000)

方法一:

my_list = list() 
print len(my_list) # prints 0

方法二:

del my_list[:] 
print len(my_list) # prints 0

我觉得方法 2 是更合适的方法,对吗?

最佳答案

在内部,Python 使用一种称为 reference counting 的机制跟踪数据是否仍可访问。每次新的“变量”引用数据时,数据的引用计数器都会增加。每次“变量”停止引用数据时,数据的引用计数器都会递减。当引用计数器达到 0 时,数据将被删除(调用其“释放函数”):http://docs.python.org/2/c-api/refcounting.html

例如,这创建了一个“大”列表,它几乎在创建后立即被删除,因为没有变量来“增加”其引用计数器:

range(1, 10000)

这将创建一个新列表,允许您通过 my_list 引用它并将列表的引用计数器设置为“1”

my_list = range(1, 10000)

编写以下语句,现在将减少列表的引用计数器。假设您没有对它的其他引用,该计数器将达到 0,因此该列表将被删除。

my_list = None

最后一个例子:

my_list = range(1, 10000)
del my_list[:]

这个创建了一个包含 10000 个项目的列表。引用计数器为“1”。第二条语句删除了列表的 10000 项——但您仍然有一个对空列表的引用。你看出区别了吗?


顺便说一句,引用计数是一种很好的自动释放机制,它具有确定性的好处(与 Java 垃圾收集器相反)。 但是,有一种情况引用计数不起作用:如果你有循环依赖。对象 A 引用对象 B,对象 B 引用对象 A。在这种情况下,只要“圆”没有被打破,A 或 B 引用计数器都不会达到 0。但这超出了你的问题,我想。无论如何,对于那些包含非掌握循环依赖的程序,Python 有一个 optional garbage collector释放这样的循环。默认情况下启用垃圾收集器。很容易检查:

>>> import gc
>>> gc.isenabled()
True

最后要注意的是,即使是垃圾收集器也是有限的,因为它不会释放包含带有终结器 (__del__) 的对象的循环。有关此 http://arctrix.com/nas/python/gc/ 的合理性,请参阅以下链接

关于python - 如何在 python 中截断列表?分配一个新的 list() 会导致内存泄漏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17121532/

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