473,289 Members | 1,756 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,289 software developers and data experts.

Producing multiple items in a list comprehension

Is there an easy way to get a list comprehension to produce a flat list of,
say, [x,2*x] for each input argument?

E.g., I'd like to do something like:

[ [x,2*x] for x in range(4) ]

....and receive

[ 0,0,1,2,2,4,3,6]

....but of course you really get a list of lists:

[[0, 0], [1, 2], [2, 4], [3, 6]]

I'm aware I can use any of the standard "flatten" bits of code to turn this
back into what I want, but I was hoping there's some way to avoid the "lists
of lists" generation in the first place?

A slightly similar problem: If I want to "merge," say, list1=[1,2,3] with
list2=[4,5,6] to obtain [1,4,2,5,3,6], is there some clever way with "zip" to
do so?

Thanks,
---Joel
Jun 27 '08 #1
13 1484
Joel Koltner wrote:
Is there an easy way to get a list comprehension to produce a flat list of,
say, [x,2*x] for each input argument?

E.g., I'd like to do something like:

[ [x,2*x] for x in range(4) ]

...and receive

[ 0,0,1,2,2,4,3,6]

...but of course you really get a list of lists:

[[0, 0], [1, 2], [2, 4], [3, 6]]

I'm aware I can use any of the standard "flatten" bits of code to turn this
back into what I want, but I was hoping there's some way to avoid the "lists
of lists" generation in the first place?

A slightly similar problem: If I want to "merge," say, list1=[1,2,3] with
list2=[4,5,6] to obtain [1,4,2,5,3,6], is there some clever way with "zip" to
do so?

Thanks,
---Joel
--
http://mail.python.org/mailman/listinfo/python-list
For the first part:

def gen(n):
for i in xrange(n):
yield i
yield 2*i

print list(gen(4))

[0, 0, 1, 2, 2, 4, 3, 6]

gerard
Jun 27 '08 #2
Joel Koltner wrote:
Is there an easy way to get a list comprehension to produce a flat list
of, say, [x,2*x] for each input argument?

E.g., I'd like to do something like:

[ [x,2*x] for x in range(4) ]

...and receive

[ 0,0,1,2,2,4,3,6]

...but of course you really get a list of lists:

[[0, 0], [1, 2], [2, 4], [3, 6]]

I'm aware I can use any of the standard "flatten" bits of code to turn
this back into what I want, but I was hoping there's some way to avoid the
"lists of lists" generation in the first place?
>>[x*y for x in range(4) for y in 1,2]
[0, 0, 1, 2, 2, 4, 3, 6]

A slightly similar problem: If I want to "merge," say, list1=[1,2,3] with
list2=[4,5,6] to obtain [1,4,2,5,3,6], is there some clever way with "zip"
to do so?
>>items = [None] * 6
items[::2] = 1,2,3
items[1::2] = 4,5,6
items
[1, 4, 2, 5, 3, 6]

Peter
Jun 27 '08 #3
Joel Koltner wrote:
Is there an easy way to get a list comprehension to produce a flat list of,
say, [x,2*x] for each input argument?

E.g., I'd like to do something like:

[ [x,2*x] for x in range(4) ]

...and receive

[ 0,0,1,2,2,4,3,6]

...but of course you really get a list of lists:

[[0, 0], [1, 2], [2, 4], [3, 6]]

I'm aware I can use any of the standard "flatten" bits of code to turn this
back into what I want, but I was hoping there's some way to avoid the "lists
of lists" generation in the first place?

A slightly similar problem: If I want to "merge," say, list1=[1,2,3] with
list2=[4,5,6] to obtain [1,4,2,5,3,6], is there some clever way with "zip" to
do so?

Thanks,
---Joel
--
http://mail.python.org/mailman/listinfo/python-list
For the first part:

def gen(n):
for i in xrange(n):
yield i
yield 2*i

print list(gen(4))

[0, 0, 1, 2, 2, 4, 3, 6]

gerard

Jun 27 '08 #4

"Joel Koltner" <za***************@yahoo.comwrote in message
news:5R*********************@en-nntp-05.dc1.easynews.com...
Is there an easy way to get a list comprehension to produce a flat list
of, say, [x,2*x] for each input argument?

E.g., I'd like to do something like:

[ [x,2*x] for x in range(4) ]

...and receive

[ 0,0,1,2,2,4,3,6]

...but of course you really get a list of lists:

[[0, 0], [1, 2], [2, 4], [3, 6]]

I'm aware I can use any of the standard "flatten" bits of code to turn
this back into what I want, but I was hoping there's some way to avoid the
"lists of lists" generation in the first place?

A slightly similar problem: If I want to "merge," say, list1=[1,2,3] with
list2=[4,5,6] to obtain [1,4,2,5,3,6], is there some clever way with "zip"
to do so?

Thanks,
---Joel
i figured out a solution

sum([x,2*x] for x in range(4)],[]) #not tested
sum(zip(list1,list2),()) #not tested

(you did say you knew of ways to flatten, but i dunno if you knew of that
way or not)

as an aside, i wish that sum didn't have to take the second parameter. it's
kind of superfluous. it can just use the first item as the initial value
instead of 0 when no initial value is specified. it would be a little
complex to do without putting a conditional in your main loop and slowing it
down, but it could be done.
Jun 27 '08 #5
On Thu, 22 May 2008 15:29:42 -0400, inhahe wrote:
"Joel Koltner" <za***************@yahoo.comwrote in message
news:5R*********************@en-nntp-05.dc1.easynews.com...
>Is there an easy way to get a list comprehension to produce a flat list
of, say, [x,2*x] for each input argument?

E.g., I'd like to do something like:

[ [x,2*x] for x in range(4) ]

...and receive

[ 0,0,1,2,2,4,3,6]

...but of course you really get a list of lists:

[[0, 0], [1, 2], [2, 4], [3, 6]]

I'm aware I can use any of the standard "flatten" bits of code to turn
this back into what I want, but I was hoping there's some way to avoid
the "lists of lists" generation in the first place?

A slightly similar problem: If I want to "merge," say, list1=[1,2,3]
with list2=[4,5,6] to obtain [1,4,2,5,3,6], is there some clever way
with "zip" to do so?

Thanks,
---Joel

i figured out a solution

sum([x,2*x] for x in range(4)],[]) #not tested sum(zip(list1,list2),())
#not tested

(you did say you knew of ways to flatten, but i dunno if you knew of
that way or not)

as an aside, i wish that sum didn't have to take the second parameter.
it's kind of superfluous. it can just use the first item as the initial
value instead of 0 when no initial value is specified. it would be a
little complex to do without putting a conditional in your main loop and
slowing it down, but it could be done.

If you don't want the second parameter use reduce():
>>reduce(operator.add, ([x, x*2] for x in xrange(4)))
[0, 0, 1, 2, 2, 4, 3, 6]
>>reduce(operator.add, zip([1,2,3],[4,5,6]))
(1, 4, 2, 5, 3, 6)

or:
>>reduce(lambda x, y: x.extend(y) or x, ([x, x*2] for x in xrange(4)))
[0, 0, 1, 2, 2, 4, 3, 6]

-- Ivan
Jun 27 '08 #6
Joel Koltner <za***************@yahoo.comwrote:
Is there an easy way to get a list comprehension to produce a flat
list of, say, [x,2*x] for each input argument?

E.g., I'd like to do something like:

[ [x,2*x] for x in range(4) ]

...and receive

[ 0,0,1,2,2,4,3,6]

...but of course you really get a list of lists:

[[0, 0], [1, 2], [2, 4], [3, 6]]
I'm not sure I would recommend it, but try:

[v for x in range(4) for v in (x, 2 * x)]
A slightly similar problem: If I want to "merge," say, list1=[1,2,3]
with list2=[4,5,6] to obtain [1,4,2,5,3,6], is there some clever way
with "zip" to do so?
A similar solution as above should work.

Marc
Jun 27 '08 #7
"Peter Otten" <__*******@web.dewrote in message
news:g1*************@news.t-online.com...
>A slightly similar problem: If I want to "merge," say, list1=[1,2,3] ...
>>>items = [None] * 6
items[::2] = 1,2,3
items[1::2] = 4,5,6
items
[1, 4, 2, 5, 3, 6]
Thanks Peter, that's pretty clean -- I like it!
Jun 27 '08 #8
"inhahe" <in****@gmail.comwrote in message
news:5P*******************@bignews7.bellsouth.net. ..
i figured out a solution

sum([x,2*x] for x in range(4)],[]) #not tested
Nice... thanks; I probably had seen code using 'sum' to flatten but hadn't
actually understood how it worked. After playing around some it's now
clear...

(Add one more opening bracket to your solution to make the interpreter
happy -- I know you know this and it was missed only due to not actually
trying it ought)

---Joel
Jun 27 '08 #9
Hi Marc,

"Marc Christiansen" <us****@solar-empire.dewrote in message
news:39************@pluto.solar-empire.de...
I'm not sure I would recommend it, but try:
[v for x in range(4) for v in (x, 2 * x)]
That certainly works... and it almost seems like a bit less of a hack (if
perhaps somewhat harder to read) than the "sum" approach to flattening?
A similar solution as above should work.
This is what I came up with:
>>list1=[1,2,3]
list2=[4,5,6]
[j for (i,m) in enumerate(list1) for j in (m,list2[i])]
[1, 4, 2, 5, 3, 6]

Not exactly "clean" due to having to enumerate list1 to get the index for
list2. There may be a better method, of course -- so far I like Petter
Otten's approach.

Thanks for the help,
---Joel
Jun 27 '08 #10
Peter Otten <__*******@web.dewrote:
A slightly similar problem: If I want to "merge," say, list1=[1,2,3] with
list2=[4,5,6] to obtain [1,4,2,5,3,6], is there some clever way with "zip"
to do so?
>items = [None] * 6
items[::2] = 1,2,3
items[1::2] = 4,5,6
items
[1, 4, 2, 5, 3, 6]
My problem with this solution is that you depend on knowing how many
elements you have in each list ahead of time. Assuming that both list
are of the same length, then, I find the following more elegant:

list1=[1,2,3]
list2=[4,5,6]

reduce(lambda x, y: x+y, zip(list1, list2))

of course, zip creates tuples, so you end up with a tuple, therefore if
you need for your solution to be a list:
list(reduce(lambda x, y: x+y, zip(list1, list2)))
of
reduce(lambda x, y: x+y, list(zip(list1, list2)) )
Yves.
http://www.SollerS.ca

Jun 27 '08 #11
Yves Dorfsman wrote:
Peter Otten <__*******@web.dewrote:
A slightly similar problem: If I want to "merge," say, list1=[1,2,3]
with list2=[4,5,6] to obtain [1,4,2,5,3,6], is there some clever way
with "zip" to do so?
>>items = [None] * 6
items[::2] = 1,2,3
items[1::2] = 4,5,6
items
[1, 4, 2, 5, 3, 6]

My problem with this solution is that you depend on knowing how many
elements you have in each list ahead of time.
$ python -m timeit -s"a = [1,2,3]*100; b = [4,5,6]*100; from operator import
add" "list(reduce(add, zip(a, b)))"
1000 loops, best of 3: 637 usec per loop

$ python -m timeit -s"a = [1,2,3]*100; b =
[4,5,6]*100" "items=[None]*(2*len(a)); items[::2] = a; items[1::2] = b"
10000 loops, best of 3: 23.4 usec per loop

The speed gain is significant. Why should I throw away useful information if
I have it? I'd even be willing to convert one arbitrary iterable to a list
to get the length information.

$ python -m timeit -s"a = [1,2,3]*100; b = [4,5,6]*100" "aa = list(a);
items=[None]*(2*len(aa)); items[::2] = aa; items[1::2] = b"
10000 loops, best of 3: 29.5 usec per loop
Assuming that both list
are of the same length, then, I find the following more elegant:

list1=[1,2,3]
list2=[4,5,6]

reduce(lambda x, y: x+y, zip(list1, list2))

of course, zip creates tuples, so you end up with a tuple, therefore if
you need for your solution to be a list:
list(reduce(lambda x, y: x+y, zip(list1, list2)))
I'd rather use a plain old for-loop:
>>from itertools import izip
a = [1,2,3]
b = [4,5,6]
items = []
for chunk in izip(a, b):
.... items.extend(chunk)
....
>>items
[1, 4, 2, 5, 3, 6]

$ python -m timeit -s"a = [1,2,3]*100; b = [4,5,6]*100; from itertools
import izip" "items = []
for chunk in izip(a, b): items.extend(chunk)"
1000 loops, best of 3: 242 usec per loop

$ python -m timeit -s"a = [1,2,3]*100; b = [4,5,6]*100; from itertools
import izip" "items = []; extend = items.extend
for chunk in izip(a, b): extend(chunk)"
10000 loops, best of 3: 70.9 usec per loop
reduce(lambda x, y: x+y, list(zip(list1, list2)) )
list(zip(...)) has no effect here. Possible fixes
>>reduce(lambda x, y: x + list(y), zip(list1, list2), [])
[1, 4, 2, 5, 3, 6]
>>reduce(lambda x, y: x.extend(y) or x, zip(list1, list2), [])
[1, 4, 2, 5, 3, 6]

$ python -m timeit -s"a = [1,2,3]*100; b = [4,5,6]*100" "reduce(lambda x, y:
x.extend(y) or x, zip(a, b), [])"
1000 loops, best of 3: 368 usec per loop

are more complicated than elegant. Not recommended.

Peter
Jun 27 '08 #12
Peter Otten <__*******@web.dewrote:
The speed gain is significant. Why should I throw away useful information if
I have it?
My thinking was that it wasn't generic enough, and I was looking for a
solution that would work for more generic problem. I agree, I shouldn't
have used the world "elegant" here, more generic would have been better.
I'd even be willing to convert one arbitrary iterable to a list
to get the length information.
$ python -m timeit -s"a = [1,2,3]*100; b = [4,5,6]*100" "aa = list(a);
items=[None]*(2*len(aa)); items[::2] = aa; items[1::2] = b"
10000 loops, best of 3: 29.5 usec per loop
Yes, I like that, it is as generic as the reduce one.

are more complicated than elegant. Not recommended.
You proved your point. Every book and webpage out there says that
functional solutions are faster than loops, that's why I tried hard not
to use a loop, and "reduce" is considered functional - I should have
timed it.
Yves.
http://www.SollerS.ca

Jun 27 '08 #13
On May 22, 7:21 pm, "Joel Koltner" <zapwireDASHgro...@yahoo.com>
wrote:
Is there an easy way to get a list comprehension to produce a flat list of,
say, [x,2*x] for each input argument?

E.g., I'd like to do something like:

[ [x,2*x] for x in range(4) ]
[x * i for x in xrange(4) for i in xrange(1, 3)]

--
Paul Hankin
Jun 27 '08 #14

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

Similar topics

23
by: Fuzzyman | last post by:
Pythons internal 'pointers' system is certainly causing me a few headaches..... When I want to copy the contents of a variable I find it impossible to know whether I've copied the contents *or*...
23
by: Stan Cook | last post by:
I was trying to take a list of files in a directory and remove all but the ".dbf" files. I used the following to try to remove the items, but they would not remove. Any help would be greatly...
2
by: Peter | last post by:
Hello! Please, could anyone tell, is it possible to set multiple items to be selected in list control in the code? For example when the web form is loaded three items of 5 are selected in list...
7
by: Jed Parsons | last post by:
Hi, I'm using the logging module for the first time. I'm using it from within Zope Extensions. My problem is that, for every event logged, the logger is producing multiple identical entries...
18
by: a | last post by:
can someone tell me how to use them thanks
4
by: Gregory Guthrie | last post by:
Sorry for a simple question- but I don't understand how to parse this use of a list comprehension. The "or" clauses are odd to me. It also seems like it is being overly clever (?) in using a...
1
NeoPa
by: NeoPa | last post by:
A number of posters have asked to be shown how to produce a list of items from multiple records which are (potentially) grouped together. Take the following data for instance (from a table called )...
3
by: pi.arctan | last post by:
Hi guys, One of my many project involves working with YUV-files, where I need to reduce the vertical resolution with a factor of two, i.e. remove every other scan line. Today I'm using two...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...

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.