繁体   English   中英

用于list()的Python内存管理

[英]Python memory management for list()

我正在创建一个元组,然后使用代码将其转换为列表:

y=("hello","the","world")
y=list(y)

python是否只是简单地将对象标记为现在可变并且可以通过标签y访问,或者它会创建每个对象的完整副本,将它们添加到新的列表结构中,然后删除原始的不可变对象?

干杯

行执行期间

y = list(y)

发生以下情况:

  1. 右侧得到评估。 这包括创建一个新的列表对象。 列表对象填充有传递给构造函数的元组对象的项目。 这些项目不会被复制。 而是增加它们的引用计数,并将对这些项目的引用添加到新的列表对象中。

  2. 将新创建的列表对象分配给左侧的名称( y )。 这包括首先取消分配名称,这导致减少之前指向的元组对象y的引用计数器。 由于不再有对该元组对象的引用,因此将其删除。 最后,将y设置为指向新的列表对象。

您可以通过检查每个对象的id来查找。

这是我跑步的结果。

y=("hello","the","world")
id(y), [id(i) for i in y]
(18627040, [21912480, 21964056, 21910304])

y = list(y)
id(y), [id(i) for i in y]
(21905536, [21912480, 21964056, 21910304])

如您所见,对象是相同的。

更新: Sven Marnach完美地解释它的方式和原因 仅供参考,我对其他类型的对象进行了更多测试。

对于物体

class C: pass
x = (C(), C(), C())
id(x), [id(i) for i in x]
(18626400, [19992128, 19992008, 19991328])
x= list(x)
id(x), [id(i) for i in x]
(21863560, [19992128, 19992008, 19991328])

对于列表

z = ([], [], [])
id(z), [id(i) for i in z]
(18627040, [21908016, 21907136, 21908536])
z = list(z)
id(z), [id(i) for i in z]
(18614992, [21908016, 21907136, 21908536])

对于列表列表

p = ([[], []], [[], []], [[], []])
id(p), [[id(i) for i in j] for j in p]
(18627040, [[21919504, 21895808], 
            [21894608, 21895008], 
            [19991008, 19789104]])
p = list(p)
id(p), [[id(i) for i in j] for j in p]
(19800352, [[21919504, 21895808], 
            [21894608, 21895008], 
            [19991008, 19789104]])

除非您明确要求,否则Python不会进行深度复制。 因此,结果将是一个新的可变列表,其中包含对与元组中对象完全相同的对象的引用。

注意,元组中的对象本身总是可变的。 这只是字符串的元组是不可变的,即不能添加/删除对象的元组,但你可以一个元组始终访问和更改对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM