What is the best way to copy a list? I know the following ways, which one is better? Or is there another way?
lst = ['one', 2, 3]
lst1 = list(lst)
lst2 = lst[:]
import copy
lst3 = copy.copy(lst)
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)
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]]
You can also do:
a = [1, 2, 3]
b = list(a)
I like to do:
lst2 = list(lst1)
The advantage over lst1[:] is that the same idiom works for dicts:
dct2 = dict(dct1)
Short lists, [:] is the best:
In [1]: l = range(10)
In [2]: %timeit list(l)
1000000 loops, best of 3: 477 ns per loop
In [3]: %timeit l[:]
1000000 loops, best of 3: 236 ns per loop
In [6]: %timeit copy(l)
1000000 loops, best of 3: 1.43 us per loop
For larger lists, they're all about the same:
In [7]: l = range(50000)
In [8]: %timeit list(l)
1000 loops, best of 3: 261 us per loop
In [9]: %timeit l[:]
1000 loops, best of 3: 261 us per loop
In [10]: %timeit copy(l)
1000 loops, best of 3: 248 us per loop
For very large lists (I tried 50MM), they're still about the same.
You can also do this:
import copy
list2 = copy.copy(list1)
This should do the same thing as Mark Roddy's shallow copy.
In terms of performance, there is some overhead to calling list()
versus slicing. So for short lists, lst2 = lst1[:]
is about twice as fast as lst2 = list(lst1)
.
In most cases, this is probably outweighed by the fact that list()
is more readable, but in tight loops this can be a valuable optimization.