-1

If i write this code

x=[1,2,3,4,[18]]
y=x
x[4][0]=15
x[1]=10
print(y)

then it outputs

[1, 10, 3, 4,[15]]

but if write like this

x=[1,2,3,4,[18]]
y=list(x)
x[4][0]=15
x[1]=10
print(y)

then it outputs

[1, 2, 3, 4, [15]]

Why is this happening?

4 Answers4

2

list() only creates a shallow copy of the original list, i.e. it only copies the references. For example, when you write:

z = [18]
x = [1, 2, 3, 4, z]
y = list(x)

x and y are different lists, but they still refer the same mutable object z. So by modifying x[4] of y[4], you update the same object z. On the other hand, x[4] = [15] will have no effect on y, because you're replacing the list element.

bereal
  • 32,519
  • 6
  • 58
  • 104
1

I suppose that list() creates a new instance of the list class. While if you make y=x is just two linked variables to one instance in the memory.

0

It's because when you write y=x they are the same list, and modifications done to either of them will be applied.

With the list(x) method you create a copy of the list in y and changes to the x original list will not be applied to y.

Chuk Ultima
  • 987
  • 1
  • 11
  • 21
  • but [18] is still changing into [15] . If new instance is created then change in x should not alter y then – RISHABH GUPTA Dec 19 '21 at 10:49
  • Integers are primary datatypes and will be copied over (by value). Lists are more complex datatypes and are not copied over, but referenced, hence that element is still linked. Look up the differences between copies and shallow copies in Python for additional information on this. – Chuk Ultima Dec 19 '21 at 10:53
  • There is no "copy by reference" or "copy by value" depending on the type of the items. The only thing is that making a shallow vs deep copy makes no difference when the items are immutable, while it does for mutable items. – Thierry Lathuille Dec 19 '21 at 11:35
0

python uses references when you assign it, which means

y = x

gives the values of x another name but behind the scenes both variables point to the same values.

On the other hand when you execute

y = list(x)

a new list with a copy of the values is being created at this point.

As a special case there is a list inside the list. This is handled in exactly the same way: in the copy only the reference to the list is copied and not the list itself. Which means that the [15] resp. [18] is the same list which can be access on two different ways (aka x[4] and y[4]).

If you want that a copy is created at all levels you need to use deepcopy like:

import copy
y = copy.deepcopy(x)
Andreas Florath
  • 4,418
  • 22
  • 32
  • That does not explain why 18 is converted into 15. if new instance is being created . That should also not changes – RISHABH GUPTA Dec 19 '21 at 10:50
  • _"a new list with a copy of the values"_ - no, `list(x)` creates a new list with the _exact same_ values. They're not copied, which is why you need `deepcopy` (if they're mutable). – jonrsharpe Dec 19 '21 at 16:21