views:

111

answers:

4

I know a list comprehension will do this, but I was wondering if there is an even shorter (and more Pythonic?) approach.

I want to create a series of lists, all of varying length. Each list will contain the same element e, repeated n times (where n = length of the list). How do I create the lists, without doing

[e for number in xrange(n)]

for each list?

+3  A: 

Itertools has a function just for that:

import itertools
it = itertools.repeat(e,n)

Of cause itertools gives you a iterator instead of a list. [e]*n gives you a list, but, depending on what you will do with those sequences, the itertools variant can be much more efficient.

THC4k
Feels too much like Java or C#. If it's faster and speed matters then use it. Otherwise use [e]*n to avoid all that excess :-)
phkahler
+5  A: 

You can also write:

[e] * n

You should note that if e is for example an empty list you get a list with n references to the same list, not n independent empty lists.

Performance testing

At first glance it seems that repeat is the fastest way to create a list with n identical elements:

>>> timeit.timeit('itertools.repeat(0, 10)', 'import itertools', number = 1000000)
0.37095273281943264
>>> timeit.timeit('[0] * 10', 'import itertools', number = 1000000)
0.5577236771712819

But wait - it's not a fair test...

>>> itertools.repeat(0, 10)
repeat(0, 10)  # Not a list!!!

The function itertools.repeat doesn't actually create the list, it just creates an object that can be used to create a list if you wish! Let's try that again, but converting to a list:

>>> timeit.timeit('list(itertools.repeat(0, 10))', 'import itertools', number = 1000000)
1.7508119747063233

So if you want a list, use [e] * n. If you want to generate the elements lazily, use repeat.

Mark Byers
+2  A: 
>>> [5] * 4
[5, 5, 5, 5]

Be careful when the item being repeated is a list.

>>> x=[5]
>>> y=[x] * 4
>>> y
[[5], [5], [5], [5]]
>>> y[0][0] = 6
>>> y
[[6], [6], [6], [6]]
Jeff
Thanks - wouldn't that be the case for all mutable elements, though, not just lists?
thebackhand
@thebackhand, yes, that's right.
Jeff
A: 
[e] * n

should work

Fabian