How to copy a list in Python?

Let me tell about a common mistake many python beginners do while trying to copy a list to another list. Suppose to copy a list listA to listB, they use listB = listA, now if you change something in one list, the other list is changed automatically as they refer to same list - actually listB points to listA! So the proper way should be
listB = []
listB.extend(listA)


Here I paste some experiments I made:
>>> listA = [1, 2, 3, 4, 5]
>>> listB = listA
>>> listC = []
>>> listC.extend(listA)
>>> listB
[1, 2, 3, 4, 5]
>>> listC
[1, 2, 3, 4, 5]
>>> listA
[1, 2, 3, 4, 5]
>>> listB[4] = 0
>>> listB
[1, 2, 3, 4, 0]
>>> listA
[1, 2, 3, 4, 0]
>>> listC
[1, 2, 3, 4, 5]
>>> listC[4] = 10
>>> listC
[1, 2, 3, 4, 10]
>>> listA
[1, 2, 3, 4, 0]
>>> listB
[1, 2, 3, 4, 0]
>>>


Hope you get the point!

Comments

Tamim Shahriar said…
Thanks. It's more Pythonic :)
Yet another idiom is

listB = list(listA)

or

from copy import copy
listB = copy(listA)

if the list contains other lists as elements or other mutable objects, these objects are not copied but also shared so you might run into similar problems on these objects. In that case the following helps:

from copy import deepcopy
listB = deepcopy(listA)
Jesse said…
Glad I found this page. This problem was ruining a Monte Carlo simulation.

Does anyone know why Python has this feature? I suppose multiple pointers to the same memory locations could be useful in some parallel programming applications, but it seems odd to make this the default.
micerinos said…
I think the best explanation for this would be to consider that in python everything is an object, and an object in python is defined by its position in memory, so you end up by using pointers all the time. Unless explicitly said, python will consider that you only want to use a reference instead of a copy of the whole data. For most applications its always more efficient, and you only have to remember that you must explicitly ask python for copying objects.
This is quite usual, also in other programming languages. For example in Java it is the same. Java doesn't have the list like Python but Java's Collection classes, in fact all Java classes act similar. An assignment is a `pointer' assignment, not a copy operation. Copying can potentially be an expensive operation therefore it is done only when explicitely asked.

In Python, assignment is in fact putting a name label (sticker) on an object. So

a = SomeList
b = a

first puts the label 'a' on SomeList, and after that it puts label 'b' on the same object. So SomeList has two labels attached to it.
Bartholomeus M. said…
Aha! That explains a lot of weird stuff - thanks for this explanation!

Popular posts from this blog

Strip HTML tags using Python

lambda magic to find prime numbers

Convert text to ASCII and ASCII to text - Python code