在 Python 2.x 中理解深拷贝与浅拷贝

Understanding Deep vs Shallow Copy in Python 2.x

我在网上查找时遇到了这 3 段代码。问题是预测输出并解释原因。

示例 1:

x = 42
y = x
x = x + 1
print x
print y

输出示例 1:

43
42

示例 2:

x = [1, 2, 3]
y = x
x[0] = 4
print x
print y

输出示例 2:

[4, 2, 3]
[4, 2, 3]

示例 3:

x = ['foo', [1,2,3], 10.4]
y = list(x) # or x[:]
y[0] = 'fooooooo'
y[1][0] = 4
print x
print y

输出示例 3:

['foo', [4, 2, 3], 10.4]
['fooooooo', [4, 2, 3], 10.4]

在大多数情况下,我知道这是一个关于浅拷贝和深拷贝的问题,但我似乎无法理解这个简单的事情。在 x[0] = 4 的示例 2 中,我了解到 xy 指向同一个对象,因此 xy 都被重新定义,而不仅仅是 x 在此语句中。但是为什么在示例 3 中没有遵循相同的逻辑。在 y[0] = 'fooooooo' 这应该会导致 xy 被重新定义,就像在 y[1][0] = 4 的下一行导致 xy 被重新定义一样一起重新定义。

好的,我们可以进一步分析一下:

>>> x = ['foo', [1,2,3], 10.4]
>>> y = list(x) # or x[:]
>>> z=x
>>> id(x)
4354889544
>>> id(y)
4354890184
>>> id(z)
4354889544

>>> y[0] = 'fooooooo'
>>> y[1][0] = 4
>>> y
['fooooooo', [4, 2, 3], 10.4]
>>> x
['foo', [4, 2, 3], 10.4]
>>> id(x[1])
4354889672
>>> id(y[1])
4354889672

现在看到了吗?当您使用函数 List() 时,它会在新的内存位置创建一个新对象...但是要保存 space python 将保留指向可变内部对象的相同指针,例如列表。 This 文章可以更多地解释什么是可变的,什么不是。