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)
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]]
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.
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.