Reputation: 217
I am trying to get a bit more intuition for how mutability of lists works in Python. In particular, I am confused by a statement in this source:
If you need to sort a list, either alphabetically or numerically, Python has you covered there as well. Just call the sort() method on the list, and it will be saved in the new order. This will overwrite the previous list, so create a copy to sort, if you need to preserve the original.
I'm not sure I understand how to implement the part in bold. Here is an example of what I'm talking about:
>>> x = [3,2,1,0]
>>> y = x
>>> x
[3,2,1,0]
>>> y
[3,2,1,0]
>>> y.sort()
>>> y
[0,1,2,3]
>>> x
[0,1,2,3]
So I created a copy to sort, then sorted the copy, but this has changed the original list. Therefore, I am confused about what the quote above is meant to mean. I don't get how this "preserves the original". Is there a special way to copy? Thanks.
Upvotes: 0
Views: 795
Reputation: 13750
When you say y = x
, you are not merely copying the data in x
to y
; you are assigning the name y
to the same underlying data that x
points to. That is, you have merely produced another name, y
, by which to reference the data already referenced by x
. So when you call y.sort()
, you also inadvertently sort x
because they reference the same underlying data.
You can copy the data referenced by x
and reference the copy with the name y
with y = list(x)
or y = x[:]
, and then sorting y
will not affect x
because they are truly different objects. Alternatively, you can use the non-mutating sort function: x_sorted = sorted(x)
.
Upvotes: 1
Reputation: 697
You should look at what is shallow copy
and deep copy
. That should be able to give you the solution to why your way of copying is not working.
Ref: https://docs.python.org/2/library/copy.html
So, when you say y = x
, that means you are copying the reference. But not exactly creating another list with different reference.
y = copy.deepcopy(x)
is deep copy, which will create another reference for y.
So modifying y
will not change any values in x.
Upvotes: 0
Reputation: 2698
You should think of these statements
x = [3,2,1,0]
y = x
as copying a reference to the list object pointed by x to y.
As both variables are a reference to the same object, sorting y leads to sorting the object that x and y point to.
To achieve the behaviour you want it would be easier to use a function that creates a sorted copy of your list
y = sorted(x)
or as the documentation says first create a copy and inplace sort the copy
y = x[:]
y.sort()
y = list(x)
y.sort()
Upvotes: 2
Reputation: 888
You are copy the references of x
You can try deepcopy to have some fun
import copy
x = [3,2,1,0]
y = copy.deepcopy(x)
y.sort()
print x
Upvotes: 1
Reputation: 869
Use y = list(x)
to create a new list. Otherwise you just get a new reference to the same list object.
Upvotes: 2