yield break in Python

PythonGeneratorYield

Python Problem Overview


According to answer to this question, yield break in C# is equivalent to return in Python. In the normal case, return indeed stops a generator. But if your function does nothing but return, you will get a None not an empty iterator, which is returned by yield break in C#

def generate_nothing():
    return

for i in generate_nothing():
    print i

You will get a TypeError: 'NoneType' object is not iterable, but if I add and never run yield before return, this function returns what I expect.

def generate_nothing():
    if False: yield None
    return

It works, but seems weird. Do you have a better idea?

Python Solutions


Solution 1 - Python

def generate_nothing():
    return
    yield

Solution 2 - Python

A good way to handle this is raising StopIteration which is what is raised when your iterator has nothing left to yield and next() is called. This will also gracefully break out of a for loop with nothing inside the loop executed.

For example, given a tuple (0, 1, 2, 3) I want to get overlapping pairs ((0, 1), (1, 2), (2, 3)). I could do it like so:

def pairs(numbers):
    if len(numbers) < 2:
        raise StopIteration

    for i, number in enumerate(numbers[1:]):
        yield numbers[i], number

Now pairs safely handles lists with 1 number or less.

Solution 3 - Python

def generate_nothing():
    return iter([])

Solution 4 - Python

The funny part is that both functions have the same bytecode. Probably there's a flag that sets to generator when bytecode compiler finds the yield keyword.

>>> def f():
...   return

>>> def g():
...   if False: yield 
#in Python2 you can use 0 instead of False to achieve the same result


>>> from dis import dis
>>> dis(f)
2           0 LOAD_CONST               0 (None) 
            3 RETURN_VALUE
>>> dis(g)
2           0 LOAD_CONST               0 (None) 
            3 RETURN_VALUE

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSonic LeeView Question on Stackoverflow
Solution 1 - PythonninjageckoView Answer on Stackoverflow
Solution 2 - PythonSam SimmonsView Answer on Stackoverflow
Solution 3 - PythonphihagView Answer on Stackoverflow
Solution 4 - PythonJBernardoView Answer on Stackoverflow