how to append to a list twice?
Alex Martelli
aleaxit at yahoo.com
Sat Apr 22 02:36:07 EDT 2006
Fredrik Lundh <fredrik at pythonware.com> wrote:
> Alex Martelli wrote:
>
> > > But of course that only does it once, and I don't want to have to copy
> > > and paste the append line. Perhaps there's a better way than this.
> >
> > def makeseries(N):
> > series = [N]
> > append = series.append
> > for tailer in xrange(N-1, -1, -1):
> > append(tailer)
> > append(tailer)
>
> But Now You've Violated The DRY Principle!!!
Just as with any other unrolled loop, yes -- loop unrolling is an
optimization which is based exactly on exchanging some textual
repetition for a tiny bit more speed.
Of course, optimizations can easily be premature, and in any case need
to be checked by measurement. E.g., here are a few variations:
def makeseries_a(N):
series = [N]
append = series.append
for tailer in xrange(N-1, -1, -1):
append(tailer)
append(tailer)
return series
def makeseries_b(N):
series = [N]
append = series.append
for tailer in xrange(N-1, -1, -1):
for x in (1,2):
append(tailer)
return series
def makeseries_c(N):
series = [N]
extend = series.extend
for tailer in xrange(N-1, -1, -1):
extend((tailer,tailer))
return series
def makeseries_d(N):
series = [N]
extend = series.extend
for tailer in xrange(N-1, -1, -1):
extend((tailer,)*2)
return series
And:
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_a(100)'
10000 loops, best of 3: 31.7 usec per loop
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_b(100)'
10000 loops, best of 3: 57.4 usec per loop
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_c(100)'
10000 loops, best of 3: 36.2 usec per loop
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_d(100)'
10000 loops, best of 3: 54.4 usec per loop
So, it would seem that (at least among these few variations) I had
guessed right, this time -- the loop-unrolling is beneficial and append
is minutely better than extend. Of course, the yanking from the loopbody
of the boundmethod is also a key optimization here -- with unyanked
(more natural) versions [[i.e., calling series.append or series.extend
right in the loop body]] I measure:
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_a(100)'
10000 loops, best of 3: 57.3 usec per loop
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_b(100)'
10000 loops, best of 3: 83.5 usec per loop
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_c(100)'
10000 loops, best of 3: 48 usec per loop
brain:~/downloads alex$ python -mtimeit -s'import rep'
'rep.makeseries_d(100)'
10000 loops, best of 3: 68.4 usec per loop
Alex
More information about the Python-list
mailing list