我正在创建一个元组,然后使用代码将其转换为列表:
y=("hello","the","world")
y=list(y)
python是否只是通过标签y标记对象现在是可变的和可达的,还是创建了每个对象的完整副本,将它们添加到新的列表结构中,然后删除原始的不可变对象?
干杯
答案 0 :(得分:14)
执行行
期间y = list(y)
发生以下情况:
评估右侧。这包括创建新的列表对象。 list对象填充了传递给构造函数的元组对象的项。这些项目不会被复制。而是增加了它们的引用计数,并且对这些项的引用被添加到新的列表对象中。
新创建的列表对象分配给左侧的名称(y
)。这包括首先取消分配名称,这会导致减少之前指向的元组对象y
的引用计数器。由于不再有对此元组对象的引用,因此将其删除。最后,y
设置为指向新列表对象。
答案 1 :(得分: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])
如您所见,对象是相同的。
更新: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]])
答案 2 :(得分:3)
Python不会进行深度复制,除非您明确要求它。因此,结果将是一个新的可变列表,其中包含与您在元组中放置的对象完全相同的对象的引用。
请注意,元组中的对象本身总是可变的。它只是字符串的元组是不可变的,即你不能向元组添加/删除对象,但你总是可以访问和更改里面的对象元组。