1

let me highlight the problem with the following code:

def genny():
    yield 1
    yield 2
    yield 3


def middleman(input_gen=None):
    if input_gen:
        gen = input_gen
    else:
        gen = genny()
    return [next(gen), gen]

if __name__ == '__main__':
    pro_list = middleman()
    pro_value = pro_list[0]
    print pro_value
    pro_gen_id = pro_list[1]
    for i in range(2):
        pro_list = middleman(pro_gen_id)
        pro_value = pro_list[0]
        print pro_value

The restriction I have is that the middleman() function cannot be a generator but I need to display all values from the generator genny(). I did this by passing back the generator object to the main() function and then sending that back again to middleman(). Is this the optimum way to do this or are there any better ways?

Rahul Sarma
  • 197
  • 15

1 Answers1

1

It's a bit hard to say without the larger context to which your example (which is understandably a toy example), is referring.

In general, it's perfectly fine to return multiple values from a function (although a tuple or namedtuple are a bit more common).

In your specific case, though, the middelman function simply nexts the generator (either received or internally constructed), then returns both this value and the generator. I don't think there's any advantage to just letting middleman create or return the generator, and let the client code do the next. The following code is equivalent to yours (see it on ideone):

def genny():
    yield 1
    yield 2
    yield 3

def middleman(input_gen=None):
    return genny() if input_gen is None else input_gen

if __name__ == '__main__':
    pro = middleman()
    for e in pro:
        pro = middleman(pro)
        print e

It's objectively shorter, and to me also clearer.

Community
  • 1
  • 1
Ami Tavory
  • 66,807
  • 9
  • 114
  • 153
  • yes it is a toy example. In the actual code, the middleman does more work than just nexting the generator. However, it must be a function and not a generator(which would have made things much easier). So basically in cases such as this, sending back the generator object or having a global variable to store the generator is the only option? – Rahul Sarma Sep 04 '16 at 17:18
  • Well, a global variable is usually not a good idea. I'd say the options are: 1. a function that returns multiple values (your question), 2. a function manipulating the generator with a single return value and the get by the client code (my answer). – Ami Tavory Sep 04 '16 at 17:23
  • can you explain what this line does: `return genny() if input_gen is None else input_gen` ? – Rahul Sarma Sep 04 '16 at 17:26
  • @RahulSarma It's a [ternary expression](http://stackoverflow.com/questions/394809/does-python-have-a-ternary-conditional-operator). With which programming language are you familiar? Maybe I can find the analog there. – Ami Tavory Sep 04 '16 at 17:30
  • oh it's a ternary expression! I got it now...I'm comfortable with python but hadn't seen return calls used in this fashion before although I have used ternary expressions before. Anyways, thanks! – Rahul Sarma Sep 04 '16 at 17:39