Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return a generator from another function

I have a generator function which I want to call from another function and return the generator obtained. I can see two approaches here -

Note that the below functions are simple dummy functions to illustrate the purpose. Please don't come up with better ways to implement those functions itself.

Method 1
def fun_a(n):
    for i in range(n):
        yield i+10

def fun_b(n):
    if n < 0: 
        yield None
        return
    yield fun_a(n)

and use it as list(list(fun_b(10))[0]) to get [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

Method 2
def fun_b(n):
    if n < 0: 
        yield None
        return
    for i in fun_a(n):
        yield i

Then list(fun_b(10)) can give me [10, 11, 12, 13, 14, 15, 16, 17, 18, 19].

While method 1 seems ok'ish, I don't want to return a list of list because in other cases I am returning a list and I don't want to mess up my code. Method 2 is just inefficient.

What would be a really good approach to deal with this situation?

like image 598
Unni Avatar asked Jul 12 '17 02:07

Unni


1 Answers

I you are using Python 3.3 or higher, you can use the yield from syntax introduced in PEP 380:

PEP 380 adds the yield from expression, allowing a generator to delegate part of its operations to another generator. This allows a section of code containing yield to be factored out and placed in another generator. Additionally, the subgenerator is allowed to return with a value, and the value is made available to the delegating generator.

>>> def fun_a(n):
    for i in range(n):
        yield i+10

>>> def fun_b(n):
    if n < 0: 
        yield None
        return
    yield from fun_a(n)


>>> list(fun_b(10))
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> 

If not, then you'll just have to use the for item in iterable: syntax.

like image 152
Christian Dean Avatar answered Nov 10 '22 06:11

Christian Dean