daikini
daikini

Reputation: 1337

How to join/merge two generators output using python

I have two generators g1 and g2

for line in g1:
    print line[0]

[a, a, a]
[b, b, b]
[c, c, c]

for line1 in g2:
    print line1[0]

[1, 1, 1]
[2, 2, 2]
[3, 3, 3]

for line in itertools.chain(g1, g2):
    print line[0]

[a, a, a]
[b, b, b]
[c, c, c]
[1, 1, 1]
[2, 2, 2]
[3, 3, 3]


How

do I get the output like:

[a, a, a],[1, 1, 1]
[b, b, b],[2, 2, 2]
[c, c, c],[3, 3, 3]

or

[a, a, a, 1, 1, 1]
[b, b, b, 2, 2, 2]
[c, c, c, 3, 3, 3]


Thank You for Your help.

Upvotes: 13

Views: 17009

Answers (4)

black panda
black panda

Reputation: 2991

first case: use

for x, y in zip(g1, g2):
    print(x[0], y[0])

second case: use

for x, y in zip(g1, g2):
    print(x[0] + y[0])

You can of course use itertools.izip for the generator version. You get the generator automatically if you use zip in Python 3 and greater.

Upvotes: 18

Stan
Stan

Reputation: 8976

Let's say you have g1 and g2 :

g1 = [
    [['a', 'a', 'a'], ['e', 'e'], ['f', 'g']],
    [['b', 'b', 'b'], ['e', 'e'], ['f', 'g']],
    [['c', 'c', 'c'], ['e', 'e'], ['f', 'g']],
]

g2 = [
    [[1, 1, 1], ['t', 'q'], ['h', 't']],
    [[2, 2, 2], ['r', 'a'], ['l', 'o']],
    [[3, 3, 3], ['x', 'w'], ['z', 'p']],
]

To get that :

[a, a, a],[1, 1, 1]
[b, b, b],[2, 2, 2]
[c, c, c],[3, 3, 3]

You can do that :

result1 = map(lambda a, b: (a[0], b[0]) , g1, g2)
# Which is like this :
[(['a', 'a', 'a'], [1, 1, 1]),
 (['b', 'b', 'b'], [2, 2, 2]),  
 (['c', 'c', 'c'], [3, 3, 3])]

And for the second :

[a, a, a, 1, 1, 1]
[b, b, b, 2, 2, 2]
[c, c, c, 3, 3, 3]

result2 = map(lambda a, b: a[0]+b[0] , g1, g2)
# Which is like that :
[['a', 'a', 'a', 1, 1, 1],
 ['b', 'b', 'b', 2, 2, 2],
 ['c', 'c', 'c', 3, 3, 3]]

Upvotes: 4

Abhijit
Abhijit

Reputation: 63737

You can use itertools.izip for example

g1=([s]*3 for s in string.ascii_lowercase)
g2=([s]*3 for s in string.ascii_uppercase)
g=itertools.izip(g1,g2)

This will ensure the resultant is also a generator.

If you prefer to use the second here is how you can do it

g1=([s]*3 for s in string.ascii_lowercase)
g2=([s]*3 for s in string.ascii_uppercase)
g=(x+y for x,y in itertools.izip(g1,g2))

Upvotes: 4

user97370
user97370

Reputation:

You can get pairs of things (your first request) using zip(g1, g2). You can join them (your second request) by doing [a + b for a, b in zip(g1, g2)].

Almost equivalently, you can use map. Use map(None, g1, g2) to produce a list of pairs, and map(lambda x, y: x + y, g1, g2) to join the pairs together.

In your examples, your generators are producing a list or tuple each time, of which you're only interested in the first element. I'd just generate the thing you need, or preprocess them before zipping or mapping them. For example:

g1 = (g[0] for g in g1)
g2 = (g[0] for g in g2)

Alternatively, you can apply [0] in the map. Here's the two cases:

map(lambda x, y: (x[0], y[0]), g1, g2)
map(lambda x, y: x[0] + y[0], g1, g2)

Upvotes: 3

Related Questions