【问题标题】:Understanding Deep vs Shallow Copy in Python 2.x理解 Python 2.x 中的深拷贝和浅拷贝
【发布时间】:2019-01-22 11:50:13
【问题描述】:

我在网上查找时遇到了这 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 一起被重新定义。

【问题讨论】:

    标签: python-2.x deep-copy shallow-copy


    【解决方案1】:

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

    >>> 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() 时,它会在新的内存位置创建一个新对象……但为了节省空间,python 将保留指向可变内部对象的相同指针,例如列表。 This 文章可以更多地解释什么是可变的,什么不是。

    【讨论】:

    • 如果y 是一个新对象list() 那么为什么y[1][0] 会指向一个共享列表而不是y 自己的值?
    • Python 试图限制新的内存空间,因此新列表仍然保留与该可变对象的原始列表的共享指针。y[1] -> mem <- x[1]
    猜你喜欢
    • 2015-01-13
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多