10.4. Modifying nested structures

Why is it important to know about the identity of compound object elements?  Look at the following:

>>> L1 = [1, [2, 3], 4]
>>> L2 = L1[:]

>>> L2[1][0] = 5
>>> L2  
[1, [5, 3], 4]
>>> L1
[1, [5, 3], 4]
      
This example modifies the first element of the list that is the second element of L2. But the second element of L1 is the same in memory as the second element of L2. That is the reason why L1 is also modified, whereas if we modify the first level of L1, L2 remains unmodified because it only changes independent references in the two lists.
>>> L1
[1, [5, 3], 4]
>>> L2
[1, [5, 3], 4]
>>> L1[1] = 6
>>> L1
[1, 6, 4]
>>> L2
[1, [5, 3], 4]
      
Figure 10.6 highlights in red the first modification and in green the second one.

Figure 10.6. Modifying compound objects

Copying references occurs also when you use variables.

>>> a = [1, 2]
>>> b = a
>>> a is b
True
>>> c = [a, 3]
>>> c
[[1, 2], 3]
>>> c[0] is a
True
>>> a[1] = 0 
>>> c
[[1, 0], 3]
>>> a
[1, 0]
>>> b
[1, 0]

>>> c[0] = 0
>>> c
[0, 3]
>>> a
[1, 0]
    

Independent copies.  It is possible to get an independent copy via the deepcopy function defined in the copy module.

>>> import copy
>>> L1
[1, 2, 4]
>>> L2
[1, [1, 3], 4]
>>> L3 = copy.deepcopy(L2)
>>> L3
[1, [1, 3], 4]
>>> L3[1] is L2[1]
False