tags:

views:

463

answers:

3

I want a list full of the same thing, where the thing will either be a string or a number. Is there a difference in the way these two list are created? Is there anything hidden that I should probably know about?

list_1 = [0] * 10

list_2 = [0 for i in range(10)]

Are there any better ways to do this same task?

Thanks in advance.

+1  A: 

I personally would advice to use the first method, since it is most likely the best performing one, since the system knows in advance the size of the list and the contents.

In the second form, it must first evaluate the generator and collect all the values. Most likely by building up the list incrementally -- what is costly because of resizing.

The first method should also be the best way at all.

Juergen
That advice is conferred by the profiling result in the Comment by SilentGhost to the post by oggy.
TokenMacGuy
+9  A: 

It depends on whether your list elements are mutable, if they are, there'll be a difference:

>>> l = [[]] * 10
>>> l
[[], [], [], [], [], [], [], [], [], []]
>>> l[0].append(1)
>>> l
[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]
>>> l = [[] for i in range(10)]
>>> l[0].append(1)
>>> l
[[1], [], [], [], [], [], [], [], [], []]

For immutable elements, the behavior of the two is the same. There might be a performance difference between them, but I'm not sure which one would perform faster.

oggy
`>>> import timeit>>> timeit.timeit("[0] * 10")0.5434829189135002>>> timeit.timeit("[0 for i in range(10)]")1.7427103316054815`
SilentGhost
difference increases with the length of a list
SilentGhost
@SilentGhost: Thanks, that seams to validate my statements.
Juergen
@oggy: Very interesting, but the "things" should be either strings or number -- both are immutable.
Juergen
@SilentGhost: nice, I suspected so but was too lazy to test. Also unsurprisingly, using xrange instead of range (in Python 2) somewhat improves the performance of the list comprehension, but not dramatically.
oggy
yeah, I should've said that I've tested on py3.1
SilentGhost
@Juergen: correct, functionally, both constructs are equivalent for strings or numbers. But the OP also asked whether there was a difference in the way the lists are constructed. There is, as shown when mutable elements are used.
oggy
+1  A: 

The first one is not only faster, but is also more readable: just by a quick look, you immediately understand what's into that list, while in the second case you have to stop and see the iteration.

Since source code is written once and read many times, for immutable elements I definitely vote for the first option.

Roberto Liffredo