1

In this SO thread it is shown that slicing is faster than anything in terms of making a copy of an item.

Using:

list1 = ['foo','bar']
copy1 = list1 * 1
list1.pop()
print 'list1: ' + list1
print 'copy1: ' + copy1

I get:

list1: ['foo']
copy1: ['foo', 'bar']

Any particular reason to stay away from making copies like this?

Community
  • 1
  • 1
  • Why not `copy1 = list(list1)`? – Peter Wood Feb 16 '15 at 15:35
  • None I can think of, except readability. As suggested ^^^^ `list(x)` is the optimal way. Also, as you can see, `x * n` is quite easy to confuse with `[x] * n` (which is entirely different ). – georg Feb 16 '15 at 15:43

2 Answers2

1

Don't forget you're duplicating a reference to the same object, which is not what you (usually) expect:

If you mean to create a list of 3 lists of '1':

>>> lst = [[1]] * 3
>>> lst
[[1], [1], [1]]

Now do something to the first one item:

>>> lst[0].append(2)

Oops, it's the same object in all three locations:

>>> lst
[[1, 2], [1, 2], [1, 2]]

I'd expect [[1, 2], [1], [1]], but that's subjective I guess, that's why I wouldn't use it. At least not with mutable objects.

Reut Sharabani
  • 30,449
  • 6
  • 70
  • 88
0

slicing is faster than anything in terms of making a copy of an item.

You can easily test this yourself:

timeit.timeit('clone = lst * 1', 'lst = ["foo", "bar"]', number=10000000)

For me, I get a time of 0.8731180049981049

The same test with a slice instead:

timeit.timeit('clone = lst [:]', 'lst = ["foo", "bar"]', number=10000000)

Gives a time of: 0.9454964299984567

So the * operator seems to actually be faster. As to why people use [:] instead? It's more obvious as to what its doing.


This breaks down when copying lists of lists, consider:

>>> lst = [[1], [2]]

Copying with a slice and with a *1 still allows for modification of the original list

>>> copy1 = lst[:]
>>> copy1[0].append('x')
>>> lst # is affected by the above
[[1, 'x'], [2]]

>>> copy2 = lst * 1
>>> copy2[0].append('y')
>>> lst # is also affected by the above
[[1, 'x', 'y'], [2]]

But with a list comprehension the sequence can be deep-copied

>>> copy3 = [l[:] for l in lst]
>>> copy3[0].append('z')
>>> lst # unaffected
[[1, 'x', 'y'], [2]]

>>> copy4 = [l * 1 for l in lst]
>>> copy4[0].append('z')
>>> lst # also unaffected
[[1, 'x', 'y'], [2]]
Ryan Haining
  • 35,360
  • 15
  • 114
  • 174