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()
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.
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.
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.
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.
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.
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
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With