Search code examples
python-2.xdeep-copyshallow-copy

Understanding Deep vs Shallow Copy in Python 2.x


I was looking online and I came across these 3 segments of code. The question is to predict the output and explain why.

Example 1:

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

Output Example 1:

43
42

Example 2:

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

Output Example 2:

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

Example 3:

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

Output Example 3:

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

For the most part I understand that this is a question about shallow and deep copying but I can't seem to wrap my head around this simple thing. In Example 2 at x[0] = 4 I understand that x and y are pointing to the same object and therefore both x and y are redefined and not just x in this statement. But then why in Example 3 does this same logic not follow. At y[0] = 'fooooooo' this should cause x and y to be redefined, just like the following line at y[1][0] = 4 causes both x and y to be redefined together.


Solution

  • Ok so we can dissect this a bit more:

    >>> 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

    See it now? When you use the function List() it is creating a new object in a new memory location... but to save space python will keep the same pointer to the mutable internal objects, like the list. This article can explain more what is mutable and what is not.