tags:

views:

570

answers:

5
lst1 = ['one', 2, 3]

// What is the best way of the following  -- or is there another way?
lst2 = list(lst1)
lst2 = lst1[:]

import copy
lst2 = copy.copy(lst1)
+25  A: 

If you want a shallow copy (elements aren't copied) use:

lst2=lst1[:]

If you want to make a deep copy then use the copy module:

import copy
lst2=copy.deepcopy(lst1)
Mark Roddy
What do you mean by elements aren't copied?
sheats
If the elements are mutable objects they are passed by reference, you have to use deepcopy to really copy them.
Andrea Ambu
It will only copy references that are held by the list. If an element in the list holds a reference to another object, that won't be copied. 9 times out of 10 you just need the shallow copy.
Jason Baker
@sheats see http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy
David Locke
+4  A: 

I often use:

lst2 = lst1 * 1

If lst1 it contains other containers (like other lists) you should use deepcopy from the copy lib as shown by Mark.


UPDATE: Explaining deepcopy

>>> a = range(5)
>>> b = a*1
>>> a,b
([0, 1, 2, 3, 4], [0, 1, 2, 3, 4])
>>> a[2] = 55 
>>> a,b
([0, 1, 55, 3, 4], [0, 1, 2, 3, 4])

As you may see only a changed... I'll try now with a list of lists

>>> 
>>> a = [range(i,i+3) for i in range(3)]
>>> a
[[0, 1, 2], [1, 2, 3], [2, 3, 4]]
>>> b = a*1
>>> a,b
([[0, 1, 2], [1, 2, 3], [2, 3, 4]], [[0, 1, 2], [1, 2, 3], [2, 3, 4]])

Not so readable, let me print it with a for:

>>> for i in (a,b): print i   
[[0, 1, 2], [1, 2, 3], [2, 3, 4]]
[[0, 1, 2], [1, 2, 3], [2, 3, 4]]
>>> a[1].append('appended')
>>> for i in (a,b): print i

[[0, 1, 2], [1, 2, 3, 'appended'], [2, 3, 4]]
[[0, 1, 2], [1, 2, 3, 'appended'], [2, 3, 4]]

You see that? It appended to the b[1] too, so b[1] and a[1] are the very same object. Now try it with deepcopy

>>> from copy import deepcopy
>>> b = deepcopy(a)
>>> a[0].append('again...')
>>> for i in (a,b): print i

[[0, 1, 2, 'again...'], [1, 2, 3, 'appended'], [2, 3, 4]]
[[0, 1, 2], [1, 2, 3, 'appended'], [2, 3, 4]]

In this case it works with copy too, because there is only one deeper level, but if you have list of lists of list of... or other objects (i took lists just for simplicity) you need deepcopy.

Andrea Ambu
+1  A: 

You can also do this:

import copy
list2 = copy.copy(list1)

This should do the same thing as Mark Roddy's shallow copy.

Jason Baker
+5  A: 

You can also do:

a = [1, 2, 3]
b = list(a)
Martin Cote
Is the result a shallow or deep copy?
minty
That would be a deep copy.
Martin Cote
No, using list() is definitely a shallow copy. Try it out.
Christian Oudard
+2  A: 

I like to do:

lst2 = list(lst1)

The advantage over lst1[:] is that the same idiom works for dicts:

dct2 = dict(dct1)
John Fouhy
There was actually a pretty long discussion about the dictionary copy versus list copy on the Python 3K mailing list:http://mail.python.org/pipermail/python-3000/2008-February/thread.html#12052
Mark Roddy
The bit of info here is that for dictionaries, you can do d = d.copy()
Christian Oudard