AlmostSurely
AlmostSurely

Reputation: 562

Modifying copy of list, modifies original

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

Answers (2)

inspectorG4dget
inspectorG4dget

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

NPE
NPE

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

Related Questions