2

I have a list x which contains another list object as below:

x = [ [1, 0] ]

Now, I am performing the concatenation operation on the list x

a = x + x
a[0][0] = 100

print(a)

Output:

[[100, 0], [100, 0]]

Here, I have not updated value of a[1][0] but it is still modified. What is causing this?

meallhour
  • 13,921
  • 21
  • 60
  • 117
  • Python wont do a deep copying when you concatenate lists. Essentially `a[0]` and `a[1]` will point to the same reference. – Ervin Szilagyi Mar 19 '22 at 22:20
  • 1
    Does this answer your question? [List of lists changes reflected across sublists unexpectedly](https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly) – Blue Robin Mar 19 '22 at 22:22
  • But isn't this `a = x[:] + x[:]` supposed to do a deep copy? Cuz this gives the same result. – re-za Mar 19 '22 at 22:23
  • `x[:]` is shallow copy. From [docs](https://docs.python.org/3/library/copy.html): Shallow copies of dictionaries can be made using `dict.copy()`, and of lists by assigning a slice of the entire list, for example, `copied_list = original_list[:]`. – Ervin Szilagyi Mar 19 '22 at 22:25
  • `a = [*x, *x]` too seems to be shallow – re-za Mar 19 '22 at 22:26

4 Answers4

2

because a after concatenation is [x,x] a[0] is accessing x which is a variable. and a[0][0] is implying to change x[0], thus changing overall x, achieving [x[0],x[0]].

Try to initialize a as [[1,0],[1,0]] and run the same command, you'll see that it'll have your desired output or x + x.copy()

[edit]

this code:

x = [5]
y = x.copy()

x[0] += 1

print(x)
print(y)

outputs:

[6]
[5]
White_Sirilo
  • 264
  • 1
  • 11
2

This is because both elements of a are pointing to the same element x. Try this very simple example:

x = [1,2]
y = x
y[0] = 10
print(x)

Surprisingly, the outcome is [10,2]. You can avoid this behavior using copy, which breaks this relationship and creates a new object.

a=x+x
a[0]=a[0].copy()
a[0][0]=100

Would do the job.

  • But this means every time one wants to change a value one has to first make a copy for that index. There should be an easy way to define `a` as a deepcopy of x + deepcoy of x – re-za Mar 19 '22 at 22:36
2

Use copy.deepcopy()

from copy import deepcopy

x = [[1, 0]]

a = deepcopy(x) + deepcopy(x)

a[0][0] = 100

Example

print(a)

Output

[[100, 0], [1, 0]]
re-za
  • 750
  • 4
  • 10
1

Another way to do this to create a copy is:

x = [ [1, 0] ]

a = [x[:],x[:]]
a[0][0] = 100

print(a)

You can create a new copy to the list instead of reference with x[:].

Output: [[100], [[1, 0]]]

Blue Robin
  • 847
  • 2
  • 11
  • 31