Reputation: 562
I thought I understood how Python handles copies of mutables, but I came upon the following behavior.
x = [i for i in xrange(5)]
mylist = [x, x]
mylist_copy = mylist[:]
mylist_copy[0].pop()
mylist
Out : [[0, 1, 2, 3], [0, 1, 2, 3]]
So it seems mylist
was changed despite changes being made only to mylist_copy
. How can I create a pure copy of mylist
so that this does not occur?
Upvotes: 2
Views: 48
Reputation: 113965
This happens not because of any copying errors when making mylist_copy
, but because mylist
is made up of two of the same elements.
mylist = [x,x] adds two references to the same object (`x`).
As a result, mylist[0].pop()
will have the same outcome:
In [70]: x = [i for i in range(5)]
In [71]: mylist = [x,x]
In [72]: mylist
Out[72]: [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]
In [73]: mylist[0].pop()
Out[73]: 4
In [74]: mylist
Out[74]: [[0, 1, 2, 3], [0, 1, 2, 3]]
Here's one way to circumvent this issue:
In [80]: x = [i for i in range(5)]
In [81]: mylist = [x, x[:]]
In [82]: mylist_copy = mylist[:]
In [83]: mylist_copy[0].pop()
Out[83]: 4
In [84]: mylist
Out[84]: [[0, 1, 2, 3], [0, 1, 2, 3, 4]]
Upvotes: 1
Reputation: 500367
While you're indeed making a copy, it is a shallow copy: mylist_copy
contains references to the original x
.
To make a deep copy, use copy.deepcopy()
.
Upvotes: 3