I have the following code and I'm wondering why it returns the same list instead of a copy:
x = [2,1,3]
y = x
y.sort()
print y
print x
Why does this return the same sorted list?
I have the following code and I'm wondering why it returns the same list instead of a copy:
x = [2,1,3]
y = x
y.sort()
print y
print x
Why does this return the same sorted list?
Because it's modified in-place.
Python lists have reference semantics, meaning that when you assign a list to another variable, they're actually pointing at the same list.
If you want to make a copy, do this:
x = [2,1,3]
y = x[:]
y.sort()
print y
print x
The slice notation does cause the list (in this case, the entire list, though you can make a small modification to ask for a particular sublist) to be copied.
You are dealing with references in Python. The statement y = x
makes y
point to the same thing as x
, so changes to y
are reflected in x
(because they point to the same underlying list).
You can change a copy by doing:
y = list(x) # make a copy of the list so we can change y without disturbing x
y.sort()
or
y = sorted(x) # return a new sorted copy of what is in x
x is the name of ("reference to") the list (object). The line
y=x
merely makes y another name for the same list. If you want to copy the list, use one of
y = x[:]
y = list(x)
(The first syntax is just an ordinary list slice, but with both the start and the end values left out, meaning that it takes the entire list.)
Note that a list is a list of objects, and copying the list will not copy the objects. If you want that behaviour — a deep copy — you must do so explicitly with
import copy
y = copy.deepcopy(x)
Naturally, this will be slower.
Assigning a list to another variable in Python creates a reference, so any changes you make to the reference will show up in the original. If you want a copy that will not alter the original, do this:
y = x[:]
Because you only copy the reference.
For instruction on how to clone the list ('deep copy'),see: How to clone or copy a list?
When you say y = x
, you're really just assigning another name (y) to the contents of x. If x is a mutable value and you do something to change it, you change the one-and-only copy that has 2 different names.
A common way to prevent this is to assign to a slice, which is always a copy of the original list.
y = x[:]