Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - is there any way to organize a group of yields in sub function to yield outside the main function?

I have a newbie question for python gurus.

I have function A that hold a lot of repeated yield-actions like so:

yield a
yield b
yield c

so it looks like:

def funA():
    …
   yield a
   yield b
   yield c
    …
   yield a
   yield b
   yield c
    …
   yield a
   yield b
   yield c

Is there any way to put all repeated yields in function and do something like that?:

def funA():
    …
   yield funB()
    …
   yield funB()
    …
   yield funB()

Update

yield a
yield b
yield c

It's just an example but in a real application its more complex sequence of yields that repeat more then once in main generator (so it's not question about organizing yields) but about sub-generators. So I'd like to avoid code duplication.

like image 657
Eugene Krevenets Avatar asked Nov 22 '13 21:11

Eugene Krevenets


People also ask

Can you yield multiple times Python?

The yield statement can run multiple times. The return statement is placed inside a regular Python function. The yield statement converts a regular function into a generator function.

Can you yield a list in Python?

The yield keyword, unlike the return statement, is used to turn a regular Python function in to a generator. This is used as an alternative to returning an entire list at once. This will be again explained with the help of some simple examples.

What can we use instead of return in Python?

Summary: The yield keyword in python works like a return with the only difference is that instead of returning a value, it gives back a generator function to the caller.

Does yield exit function Python?

The keyword yield causes the function to hand back a generator object to its caller. yield will not cause the function to exit nor terminate the loop. A generator can be parsed into a list.


2 Answers

If you're using the latest and greatest python (>= 3.3), there's the yield from construct.

yield from funB()

It does exactly what you want: you can invoke a function as a sub-generator, and yield back everything it yields to you.

If you're using an earlier version of python, then I'm afraid you'll have to do it manually:

for x in funB(): yield x

If you have a dynamic set of sub-generators, you can do this:

funs = [funA, funB, funC]

for fun in funs:
    for item in fun():
        yield item
like image 68
slezica Avatar answered Oct 14 '22 00:10

slezica


itertools.chain is the function you're looking for

import itertools

def funA():
    for x in range(10):
        yield x

def funB():
    for x in range(10,20):
        yield x

def funC():
    for x in range(20,30):
        yield x

def funs():
    for x in itertools.chain(funA(), funB(), funC()):
        yield x

print [x for x in funs()]

Outputs:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
like image 3
Rebs Avatar answered Oct 14 '22 00:10

Rebs