Neal D. Becker said:
What is the recommended way to create a sequence of objects? Assume the
objects have a default constructor:
class X:
def __init__(self):
something
This doesn't work:
a = 64*(X(),)
This creates a tuple of 64 copies of a single identical object, not 64
instances of X.
I could create an empty list, then call append (X()) 64 times, but that's
not very eligant (or maybe efficient). Any suggestions?
I suspect you can't do much better than a list comprehension:
a = [X() for i in xrange(64)]
A _little_ better, maybe, with itertools:
import itertools as it
a = [X() for i in it.repeat(0,64)]
or even:
a = list(it.starmap(X, it.repeat((), 64)))
The itertools-based solutions DO go faster on my machine (at least with
Python2.4):
kallisti:~/cb alex$ python2.4 timeit.py -s'class X
ass' -s'import
itertools as it' '[X() for i in xrange(64)]'
1000 loops, best of 3: 208 usec per loop
kallisti:~/cb alex$ python2.4 timeit.py -s'class X
ass' -s'import
itertools as it' '[X() for i in it.repeat(0,64)]'
10000 loops, best of 3: 168 usec per loop
kallisti:~/cb alex$ python2.4 timeit.py -s'class X
ass' -s'import
itertools as it' 'list(it.starmap(X, it.repeat((), 64)))'
10000 loops, best of 3: 138 usec per loop
However, unless you're really squeezed for cycles (which is why I'm
doing the measurements with 2.4: if you ARE squeezed, upgrading to 2.4
and its generally better speed may be urgent for you), the simplicity of
the list comprehension may probably be preferable to these speedups (at
20% or even 35%, they sure look yummy, but remember, this is with a
class without even an __init__ -- add an __init__ doing any substantial
work, and the relative % speedup will decrease).
Alex