List Comprehension Question: One to Many Mapping?

B

beginner

Hi All,

How do I map a list to two lists with list comprehension?

For example, if I have x=[ [1,2], [3,4] ]

What I want is a new list of list that has four sub-lists:

[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]

[1,2] is mapped to [1,2] and [f(1), f(2)] and [3,4] is mapped to
[3,4], [f(3), f(4)].

I just can't find any way to do that with list comprension. I ended up
using a loop (untested code based on real code):

l=[]
for y in x:
l.append(y)
l.append([f(z) for z in y])

Thanks,
Geoffrey
 
A

attn.steven.kuo

Hi All,

How do I map a list to two lists with list comprehension?

For example, if I have x=[ [1,2], [3,4] ]

What I want is a new list of list that has four sub-lists:

[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]

[1,2] is mapped to [1,2] and [f(1), f(2)] and [3,4] is mapped to
[3,4], [f(3), f(4)].

I just can't find any way to do that with list comprension. I ended up
using a loop (untested code based on real code):

l=[]
for y in x:
l.append(y)
l.append([f(z) for z in y])


Suppose f is:

Using a list comprehension:
[i for i in itertools.chain(*[(eachx, [f(y) for y in eachx]) for eachx in x])]
[[1, 2], ['1', '2'], [3, 4], ['3', '4']]


Using a list:
list(itertools.chain(*[(eachx, [f(y) for y in eachx]) for eachx in x]))
[[1, 2], ['1', '2'], [3, 4], ['3', '4']]


Not so pretty in either case.
 
P

Peter Otten

beginner said:
How do I map a list to two lists with list comprehension?

For example, if I have x=[ [1,2], [3,4] ]

What I want is a new list of list that has four sub-lists:

[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]

[1,2] is mapped to [1,2] and [f(1), f(2)] and [3,4] is mapped to
[3,4], [f(3), f(4)].

I just can't find any way to do that with list comprension.
[a for b in ((item, map(f, item)) for item in x) for a in b]
[[1, 2], [f(1), f(2)], [3, 4], [f(3), f(4)]]
I ended up
using a loop (untested code based on real code):

l=[]
for y in x:
l.append(y)
l.append([f(z) for z in y])

Using a loop gives you clearer code in this case, so I'd use that.

Peter
 
D

Davo

Hi All,

How do I map a list to two lists with list comprehension?

For example, if I have x=[ [1,2], [3,4] ]

What I want is a new list of list that has four sub-lists:

[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]

[1,2] is mapped to [1,2] and [f(1), f(2)] and [3,4] is mapped to
[3,4], [f(3), f(4)].

I just can't find any way to do that with list comprension. I ended up
using a loop (untested code based on real code):

l=[]
for y in x:
l.append(y)
l.append([f(z) for z in y])

Thanks,
Geoffrey

This may be what you want:

l = [[y, [f(z) for z in y]] for y in x]

But It's a bit dense. How about:
l=[]
for y in x:
Fy = [f(z) for z in y]
l.extend([y, Fy])

-- David
 
B

beginner

How do I map a list to two lists with list comprehension?
For example, if I have x=[ [1,2], [3,4] ]
What I want is a new list of list that has four sub-lists:
[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]
[1,2] is mapped to [1,2] and [f(1), f(2)] and [3,4] is mapped to
[3,4], [f(3), f(4)].
I just can't find any way to do that with list comprension. I ended up
using a loop (untested code based on real code):
l=[]
for y in x:
l.append(y)
l.append([f(z) for z in y])
Thanks,
Geoffrey

This may be what you want:

l = [[y, [f(z) for z in y]] for y in x]

But It's a bit dense. How about:
l=[]
for y in x:
Fy = [f(z) for z in y]
l.extend([y, Fy])

-- David- Hide quoted text -

- Show quoted text -

This is exactly what I was looking for. Thanks.
 
P

Paul Rubin

beginner said:
For example, if I have x=[ [1,2], [3,4] ]

What I want is a new list of list that has four sub-lists:

[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]

[[a, map(f,a)] for a in x]
 
B

Boris Borcic

Paul said:
beginner said:
For example, if I have x=[ [1,2], [3,4] ]

What I want is a new list of list that has four sub-lists:

[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]

[[a, map(f,a)] for a in x]

no, that one will be [[[1,2], [f(1), f(2)]], [[3,4], [f(3), f(4)]]]
eg two sublists instead of four.

[map(g,a) for a in x for g in [None,f]]

will do it.

....a bit too cleverly, but there's worse :

list((yield a) or map(f,a) for a in x)

Cheers, BB
 
P

Paul Rubin

Boris Borcic said:
For example, if I have x=[ [1,2], [3,4] ]

What I want is a new list of list that has four sub-lists:

[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]
[[a, map(f,a)] for a in x]

no, that one will be [[[1,2], [f(1), f(2)]], [[3,4], [f(3), f(4)]]]
eg two sublists instead of four.

Oh ugh, I misread the original request and thought the extra brackets
were there. I think the following works and is reasonably intuitive:

from itertools import chain
y = list(chain(*([a, map(f,a)] for a in x)))

But the original request itself seems a bit weird.
 
B

beginner

Hi All,
How do I map a list to two lists with list comprehension?
For example, if I have x=[ [1,2], [3,4] ]
What I want is a new list of list that has four sub-lists:
[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]
[1,2] is mapped to [1,2] and [f(1), f(2)] and [3,4] is mapped to
[3,4], [f(3), f(4)].
I just can't find any way to do that with list comprension. I ended up
using a loop (untested code based on real code):
l=[]
for y in x:
l.append(y)
l.append([f(z) for z in y])
Thanks,
Geoffrey
This may be what you want:
l = [[y, [f(z) for z in y]] for y in x]
But It's a bit dense. How about:
l=[]
for y in x:
Fy = [f(z) for z in y]
l.extend([y, Fy])
-- David- Hide quoted text -
- Show quoted text -

This is exactly what I was looking for. Thanks.- Hide quoted text -

- Show quoted text -

On second thought, that will generate one additional level. So it is
not what I am looking for.
 
B

beginner

Boris Borcic said:
For example, if I have x=[ [1,2], [3,4] ]
What I want is a new list of list that has four sub-lists:
[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]
[[a, map(f,a)] for a in x]
no, that one will be [[[1,2], [f(1), f(2)]], [[3,4], [f(3), f(4)]]]
eg two sublists instead of four.

Oh ugh, I misread the original request and thought the extra brackets
were there. I think the following works and is reasonably intuitive:

from itertools import chain
y = list(chain(*([a, map(f,a)] for a in x)))

But the original request itself seems a bit weird.

Not so werid. :) Just to put this into context, I have a list of list
of objects x=[[o1, o2, o3, o4], [o5,o6]]

I was trying to plot them with matplotlib. Each sub-list is a line. So
I would have to re-organize the list to be like the following:

v=[[o1.x, o2.x, o3.x, o4.x], [o1.y, o2.y, o3.y, o4.y], [o5.x, o6.x],
[o5.y, o6.y]]

So that I can pass it to plot:

plot(*tuple(v))

I like the chain and map solutions.
 
Z

ZeD

Boris said:
For example, if I have x=[ [1,2], [3,4] ]
What I want is a new list of list that has four sub-lists:
[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]
[[a, map(f,a)] for a in x]
[map(g,a) for a in x for g in [None,f]]
will do it.

...a bit too cleverly, but there's worse :
list((yield a) or map(f,a) for a in x)

worse (in *many* ways) solutions:

l = [[a, map(f,a)] for a in x]

1) s = sum(l, [])

2) from operator import add
r = reduce(add, l, [])

3) a = []
for e in l: a.extend(e)
 
E

Eduardo O. Padoan

For example, if I have x=[ [1,2], [3,4] ]
What I want is a new list of list that has four sub-lists:

[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]

[[a, [f(b) for b in a]] for a in x]
 
B

beginner

Paul said:
beginner said:
For example, if I have x=[ [1,2], [3,4] ]
What I want is a new list of list that has four sub-lists:
[[1,2], [f(1), f(2)], [3,4], [f(3), f(4)]]
[[a, map(f,a)] for a in x]

no, that one will be [[[1,2], [f(1), f(2)]], [[3,4], [f(3), f(4)]]]
eg two sublists instead of four.

[map(g,a) for a in x for g in [None,f]]

will do it.

...a bit too cleverly, but there's worse :

list((yield a) or map(f,a) for a in x)

Cheers, BB

Really cool!
 

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,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top