473,405 Members | 2,185 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

how to append to a list twice?

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.
Apr 21 '06 #1
26 10044
"John Salerno" <jo******@NOSPAMgmail.com> wrote in message
news:ui******************@news.tufts.edu...
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)
Apr 21 '06 #2

John Salerno wrote:
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

Apr 21 '06 #3
John Salerno <jo******@NOSPAMgmail.com> wrote:
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
Apr 21 '06 #4
> 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


Apr 21 '06 #5
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

Apr 21 '06 #6
Paul McGuire wrote:
"John Salerno" <jo******@NOSPAMgmail.com> wrote in message
news:ui******************@news.tufts.edu...
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.
Apr 21 '06 #7
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!!!

</F>

Apr 21 '06 #8
> 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


Apr 21 '06 #9

Gerard Flanagan wrote:
John Salerno wrote:
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']
---------------------------------------------------------

Gerard

Apr 21 '06 #10
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
--
The problem with the world is stupidity. Not saying there should be a
capital punishment for stupidity, but why don't we just take the
safety labels off of everything and let the problem solve itself?
Frank Zappa
Apr 21 '06 #11
John Salerno <jo******@NOSPAMgmail.com> wrote:
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.

--
\S -- si***@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
___ | "Frankly I have no feelings towards penguins one way or the other"
\X/ | -- Arthur C. Clarke
her nu becomež se bera eadward ofdun hlęddre heafdes bęce bump bump bump
Apr 21 '06 #12
John Salerno wrote:
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)]
Apr 21 '06 #13
Gerard Flanagan wrote:
Gerard Flanagan wrote:
John Salerno wrote:
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

Apr 21 '06 #14
Edward Elliott wrote:
John Salerno wrote:
> 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! :)
Apr 21 '06 #15
John Salerno wrote:
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/
Apr 21 '06 #16
Edward Elliott <no****@127.0.0.1> wrote:
John Salerno wrote:
> 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

--
Nick Craig-Wood <ni**@craig-wood.com> -- http://www.craig-wood.com/nick
Apr 21 '06 #17
Nick Craig-Wood wrote:
That should be

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

to be "from __future__ import division" safe


from __present__ import gratitude
Apr 21 '06 #18
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?

Apr 21 '06 #19
ca********@gmail.com wrote:
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.
Apr 21 '06 #20
John Salerno wrote:
ca********@gmail.com wrote:
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.


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.
Apr 21 '06 #21
On 21 Apr 2006 12:50:38 -0700 in comp.lang.python,
ca********@gmail.com wrote:
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

--
Change is inevitable, progress is not.
Apr 21 '06 #22
John Salerno wrote:
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...?)

Apr 21 '06 #23
John Salerno wrote:
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
Apr 21 '06 #24
Fredrik Lundh <fr*****@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
Apr 22 '06 #25
Alex Martelli wrote:
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.


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>

Apr 22 '06 #26

"Fredrik Lundh" 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!!!


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

pepr
Apr 24 '06 #27

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

25
by: Yves Glodt | last post by:
Hello, if I do this: for row in sqlsth: ________pkcolumns.append(row.strip()) ________etc without a prior:
2
by: jeremito | last post by:
I have created a class that inherits from the list object. I want to override the append function to allow my class to append several copies at the same time with one function call. I want to do...
13
by: HMS Surprise | last post by:
Trying not to be a whiner but I sure have trouble finding syntax in the reference material. I want to know about list operations such as append. Is there a pop type function? I looked in tutorial,...
10
by: HYRY | last post by:
I have the following questions, I am using Python 2.4.2 19167152 #1 11306608 #1 1. the address of a.append and list.append is different, can I get the address of...
42
by: Armin | last post by:
Hi, just a dumb question. Let a = Why is the value of a.append(7) equal None and not ?? --Armin
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.