1

I have a code snippet below:

def yield_5():
    for i in range(5):
        yield i

def foo(use_yield):
    if use_yield:
        for i in yield_5():
            yield i
    else:
        return list(yield_5())

When I do list(foo(True)) I get: [0, 1, 2, 3, 4] as expected

But when I do: foo(False) I get: []

Why is this the case?

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
YellowPillow
  • 4,100
  • 6
  • 31
  • 57

1 Answers1

0

In python, as in most langauges, this is a form of lazy enumeration. What gets returned is a Generator, the values of which are only actually created when the next value is required.

This is actually the reason that the word yield is commonly used for this. When you call the function which contains a yield statement, it will immediately return (yield) control back to the controlling function. When the first value of the Generator is required, it will run the function up until it hits the first Yield statement, then it will return (yield) control back to the parent function. It will continue this pattern. Once the last Yield value is exercised (the end of the Yielding function is reached), that is considered the 'end' of the iterable.

In your example, the confusion is that you have both yield and return in the foo() function. When this occurs, the return functions as a StopIteration (hence why you get an empty array). See this questionhere: Return and yield in the same function

David Colwell
  • 2,450
  • 20
  • 31