how to append to a list twice?

J

John Salerno

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.
 
P

Paul McGuire

John Salerno 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]
for x in range(10): # just for testing
series.extend([series[-1] - 1]*2)
 
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]

for i in range(1,10):
series.extend([100-i]*2)

print series

[100, 99, 99, 98, 98, 97, 97, 96, 96, 95, 95, 94, 94, 93, 93, 92, 92,
91, 91]

Gerard
 
A

Alex Martelli

John Salerno 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.

def makeseries(N):
series = [N]
append = series.append
for tailer in xrange(N-1, -1, -1):
append(tailer)
append(tailer)
return series

series = makeseries(100)

assuming that by "most efficiently" you mean "fastest", this might come
close; you'll want to also time an alternative where makeseries is a
generator which just yields the values, and the last assignment becomes
series=list(makeseries(100)).


Alex
 
T

Tim Chase

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)

Well, you can do something like

def foo(start):
count = 0
while 1:
yield start - ((count + 1) / 2)
count += 1

which is pretty efficient in the matter. If you just need
the results, you can do something like

series = [100]
for _ in range(10):
series.extend([x[-1]-1]*2)

Both should get you what you want, and one or the other may
be better depending on the scenario in which you want to use it.

-tkc
 
D

danmcleran

Not sure if this is simpler or better, but here's a way to do it with a
generator:

value = 100
count = 0

def valueGen():
global value
global count
while(value >= 0):
if(value == 100):
yield value
value -= 1
else:
if(count & 1):
yield value
else:
yield value
value -= 1

count = count + 1

series = []
gen = valueGen()

for item in gen:
print item
series.append(item)

print series
 
J

John Salerno

Paul said:
John Salerno 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]
for x in range(10): # just for testing
series.extend([series[-1] - 1]*2)

Interesting. I tried the *2 method twice, but I kept getting weird
results, I guess because I was using append and not extend. I thought
extend added lists to lists, but obviously that's not the case here.

Thanks.
 
F

Fredrik Lundh

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!!!

</F>
 
T

Tim Chase

Interesting. I tried the *2 method twice, but I kept
getting weird results, I guess because I was using append
and not extend. I thought extend added lists to lists,
but obviously that's not the case here.


In the above example, it *is* "add[ing] lists to lists".
Note the set of brackets:

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

You have a one-element series:

[series[-1] - 1]

that gets duplicated using the overloading of the
multiplication ("duplication") operator:

[...] * 2

This yields a two-element list. This list then gets passed
to extend(), to add those two elements to the original list.

If you used append() instead of extend(), it would be
something like

[100, [99, 99], [98, 98],...]

-tkc
 
G

Gerard Flanagan

Gerard said:
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]

for i in range(1,10):
series.extend([100-i]*2)

print series

[100, 99, 99, 98, 98, 97, 97, 96, 96, 95, 95, 94, 94, 93, 93, 92, 92,
91, 91]

Alternative:

---------------------------------------------------------
series = [100]

r = xrange(99,90,-1)

for L in ( [a1,a2] for a1,a2 in zip( r, r ) ):
series.extend(L)

print series

out: [100, 99, 99, 98, 98, 97, 97, 96, 96, 95, 95, 94, 94, 93, 93, 92,
92, 91, 91]

---------------------------------------------------------
series = ['a']

r = 'bcdefgh'

for L in ( [a1,a2] for a1,a2 in zip( r, r ) ):
series.extend(L)

print series

out: ['a', 'b', 'b', 'c', 'c', 'd', 'd', 'e', 'e', 'f', 'f', 'g', 'g',
'h', 'h']
 
S

Sybren Stuvel

John Salerno enlightened us with:
Interesting. I tried the *2 method twice, but I kept getting weird
results, I guess because I was using append and not extend. I
thought extend added lists to lists, but obviously that's not the
case here.

[100].extend([90]) -> [100, 90]
[100].append([90]) -> [100, [90]]
[100].append(90) -> [100, 90]

Sybren
 
S

Sion Arrowsmith

John Salerno 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, [ ... ]

You could try:

series = [100]
l = range(series[-1]-1, series[-1]-11, -1) #just for testing
s.extend(sum(zip(l, l), ()))

Times as faster than the series.extend([series[-1] - 1] * 2)
for me.
 
E

Edward Elliott

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?

Why not just this:

series = [x/2 for x in range(200, 1, -1)]
 
G

Gerard Flanagan

Gerard said:
Gerard said:
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]

for i in range(1,10):
series.extend([100-i]*2)

print series

[100, 99, 99, 98, 98, 97, 97, 96, 96, 95, 95, 94, 94, 93, 93, 92, 92,
91, 91]

Alternative:

---------------------------------------------------------
series = [100]

r = xrange(99,90,-1)

for L in ( [a1,a2] for a1,a2 in zip( r, r ) ):
series.extend(L)

print series

out: [100, 99, 99, 98, 98, 97, 97, 96, 96, 95, 95, 94, 94, 93, 93, 92,
92, 91, 91]

---------------------------------------------------------
series = ['a']

r = 'bcdefgh'

for L in ( [a1,a2] for a1,a2 in zip( r, r ) ):
series.extend(L)

print series

out: ['a', 'b', 'b', 'c', 'c', 'd', 'd', 'e', 'e', 'f', 'f', 'g', 'g',
'h', 'h']

(Nothing better to do!)

def multiplier( iterable, n ):
for t in zip( *[iterable] * n):
yield t

series1 = [100]
rng = xrange(99,90,-1)

for L in multiplier( rng, 2 ):
series1.extend(L)

series2 = ['a']
rng = 'bcdefgh'
for L in multiplier( rng, 2 ):
series2.extend(L)

print series1
print series2

Gerard
 
J

John Salerno

Edward said:
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?

Why not just this:

series = [x/2 for x in range(200, 1, -1)]

clever! :)
 
J

James Stroud

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.

I know this doesn't beat Edward Elliot's answer, but:

py> import operator
py> [100] + reduce(operator.add, [[i,i] for i in xrange(99,90,-1)])
[100, 99, 99, 98, 98, 97, 97, 96, 96, 95, 95, 94, 94, 93, 93, 92, 92,
91, 91]


--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
N

Nick Craig-Wood

Edward Elliott said:
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?

Why not just this:

series = [x/2 for x in range(200, 1, -1)]

That should be

series = [x//2 for x in range(200, 1, -1)]

to be "from __future__ import division" safe
 
E

Edward Elliott

Nick said:
> That should be
>
> series = [x//2 for x in range(200, 1, -1)]
>
> to be "from __future__ import division" safe

from __present__ import gratitude
 
C

callmebill

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?
 
J

John Salerno

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?

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.
 

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

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,277
Latest member
VytoKetoReview

Latest Threads

Top