4

Copying an element back into the list:

>> a = [[1,2],[3,4]]
>> b = []
>> b = a[1]
>> a.insert(1,b)
>> a
[[1,2],[3,4],[3,4]]
>> a[2][0] = 0
>> a
???

What do you expect list 'a' to be? It comes out to be as [[1,2],[0,4],[0,4]] which was very surprising to me whereas I expected [[1,2],[1,4],[0,4]]

I kind of know the answer but still, the idea is not very clear. Kindly tell in more detail why does this happen and how to get rid of it?

2 Answers2

6
b = a[1]
a.insert(1,b)

b is a reference to a[1] so when you modify the reference after inserting it, it appears in both places since it is essentially pointing to the same data.

if you want to avoid such a scenario, use deepcopy

from copy import deepcopy

a = [[1,2],[3,4]]
b = []
b = deepcopy(a[1])
a.insert(1,b)
print(a) # prints [[1, 2], [3, 4], [3, 4]]
a[2][0] = 0
print(a) # prints [[1, 2], [3, 4], [0, 4]]
PYA
  • 8,096
  • 3
  • 21
  • 38
  • I think `deepcopy(a[1])` is doing similar to what `list(a[1])` would do. – Sunal Mittal Jul 13 '17 at 10:35
  • 1
    @SunalMittal yes check out https://docs.python.org/2/library/functions.html#func-list – PYA Jul 13 '17 at 14:13
  • 1
    But be aware that copy.copy(), list[:] and list(list), unlike copy.deepcopy() and the python version don't copy any lists, dictionaries and class instances in the list, so if the originals change, they will change in the copied list too and vice versa. more here https://stackoverflow.com/a/2612990/7821988 – PYA Jul 13 '17 at 14:17
3

The reason is because of the way lists work in python, they have what is known as "linked data". If you have an instance pointing to an object in a list, and then modify that object, it will be modified in the list too because the list simply points to the object(s). So:

x = [1,2]
b = [1,3]
x[0] = b
b[0] = 2

Then printing x would give [[2,3],2] not [[1,3],2].

What's happening in your situation is that you set the object at position 1 of a to be a pointer/variable b. Then you inserted that pointer at position 2 of a. So when you modify position 2 of a, you also modify b, and thus modify position 1 of a.

Cary Shindell
  • 1,336
  • 8
  • 25