列表的Python内存管理()

Chr*_*ris 7 python

我正在创建一个元组,然后将其转换为包含以下代码的列表:

y=("hello","the","world")
y=list(y)
Run Code Online (Sandbox Code Playgroud)

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

干杯

Sve*_*ach 14

在执行该行期间

y = list(y)
Run Code Online (Sandbox Code Playgroud)

发生以下情况:

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

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


Pra*_*ota 10

您可以通过检查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])
Run Code Online (Sandbox Code Playgroud)

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

更新: 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])
Run Code Online (Sandbox Code Playgroud)

列表

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])
Run Code Online (Sandbox Code Playgroud)

列表清单

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]])
Run Code Online (Sandbox Code Playgroud)