pythonlistdeep-copy

Why changing inner element changes the element of copied list, but changing the whole element does not


I know about deep copy in Python, but I need exact explanation of what happens after changing the first element of a, or maybe the explanation of happens here.

>>> a=[[0,1],[2,3]]
>>> b=list(a)
>>> a
[[0, 1], [2, 3]]
>>> b
[[0, 1], [2, 3]]
>>> a[0]=[9,10]
>>> a
[[9, 10], [2, 3]]
>>> b
[[0, 1], [2, 3]]
>>> a[1][0]=11
>>> a
[[9, 10], [11, 3]]
>>> b
[[0, 1], [11, 3]]
>>> 

Solution

  • I think the confusion arises from how shallow copies work in Python and how the elements are referenced. To break down what happens in your code snippets:

    When you perform b = list(a), a shallow copy of the list a is created. This means that b is a new list object, but the inner lists within a are not copied. Instead, both a and b still reference the same inner lists -> So you're basically copying the outer list, but not the stuff inside. This means b gets its outer list, but both a and b still share the same inner lists.

    Now, when you do this:

    a[1][0] = 11
    

    You are modifying one of the elements within the inner list. Since both a[1] and b[1] still refer to the same inner list, the change you make in a[1][0] also appears in b[1][0].

    But when you replace an entire element (the entire inner list):

    a[0] = [9, 10]
    

    In this case, you're replacing the entire inner list a[0] (the whole object) with a new list [9, 10]. A new reference is created. Since b only holds a reference to the original list at position b[0] (which was [0, 1]), this assignment does not affect b[0]. The reference in b is unchanged, so b[0] still points to the old list [0, 1], while a[0] points to the new list [9, 10].