how to append to a list twice?

J

John Salerno

John said:
Because of the way division works. The first number in the range is 200,
and 200/2 is 100. The next number is 199, and 199/2 is (as division
works right now) 99 (99.5 rounded). Next is 198, and that halved is also
99 (this time with no remainder). Every two sets of numbers thereafter
also do the same.

I should also say, to answer your question more directly, that the
reason it doesn't happen to the first number is because it only works on
an odd number and the number below it, i.e. 199 and 198 both yield 99.
If our range had started with 201, then 100 would have been repeated twice.
 
D

Dave Hansen

On 21 Apr 2006 12:50:38 -0700 in comp.lang.python,
I don't get it (the Elliot solution)... How is it that the first value
is repeated once times, and the remaining values are repeated twice
times?

Integer division truncates. 200/2 -> 100, 199/2 -> 99, 198/2 -> 99,
etc. Regards,

-=Dave
 
G

Gerard Flanagan

John said:
If I want to create a list of the form [100, 99, 99, 98, 98, 97, 97...]
(where each item is repeated twice after the first one), how might I do
that most efficiently?

Right now I have this:

series = [100]
for x in range(10): # just for testing
series.append(series[-1] - 1)

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.

Thanks.


series = [100] + [ t for t in range(99,90,-1) for _ in [0,1] ]

(what's wrong with two appends again...?)
 
P

Peter Otten

John said:
If I want to create a list of the form [100, 99, 99, 98, 98, 97, 97...]
(where each item is repeated twice after the first one), how might I do
that most efficiently?

series = [100]*21
series[1::2] = series[2::2] = range(99, 89, -1)

:)

Peter
 
A

Alex Martelli

Fredrik Lundh said:
Alex said:
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
 
F

Fredrik Lundh

Alex said:
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.

I had hoped that the Unusual Capitalization would have been enough
to make up for the missing smiley...

(but note that the OP explicitly didn't want to copy and paste; given
that he wrote a newsgroup posting instead seems to indicate that his
programming editor isn't quite as good as the editor in his newsreader)

</F>
 
P

Petr Prikryl

Fredrik Lundh said:
Alex said:
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!!!

Do you mean the "three times -1" in the xrange arguments? :)

pepr
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Forum statistics

Threads
474,294
Messages
2,571,511
Members
48,197
Latest member
ปั๊มเฟส|JoyLikeSEO

Latest Threads

Top