我在看这个家伙的帖子: https://stackoverflow.com/a/2573965/1959054
他正在谈论测试人们的Python熟练程度,向他们询问以下代码的输出:
x = 42
y = x
x = x+1
print x
print y
x = [1,2,3]
y = x
x[0]=4
print x
print y
我成功预测了这两个输出,刚刚阅读了书中可变列表和不可变字符串的类似场景。然后他举了这个例子:
x = ["foo",[1,2,3],10.4]
y = list(x)
y[0] = 'foooooo'
y[1][0] = 4
print x
print y
这让我很困惑。您看,我预测x
将打印为["foo",[1,2,3],10.4]
而y
将打印为["foooooo",[4,2,3],10.4]
。
x
实际打印为["foo",[4,2,3],10.4]
,这意味着,即使外部列表引用了不同的list
个对象,x[1]
和y[1]
的内部列表也是如此仍然引用同一个对象。
我以前没遇到过这个。
我的主要问题是,如果您想使y
等同于x
,但不引用相同的列表,并且还要确保任何嵌套列表都不引用相同的列表,你是怎样做的? y = list(x)
似乎只处理外部列表。
我的第二个问题就是从概念上理解为什么这样做会有所帮助。
答案 0 :(得分:1)
您的第一个问题由copy.deepcopy()
回答,docs):
构造一个新的复合对象,然后递归地将副本插入到原始对象中找到的对象。
from copy import deepcopy
y = deepcopy(x)
至于为什么会发生这种情况,list()
(以及公共slice
副本x[:]
)的标准列表构建只会创建一个浅层副本,即(再次提供文档,强调我的):
构造一个新的复合对象,然后(尽可能)将引用插入到原始对象中找到的对象。