What is the best way to copy a list?

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)

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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)

Method 2

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

Method 3

You can also do:

a = [1, 2, 3]
b = list(a)

Method 4

I like to do:

lst2 = list(lst1)

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

dct2 = dict(dct1)

Method 5

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.

Method 6

You can also do this:

import copy
list2 = copy.copy(list1)

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

Method 7

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.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x