yield break in Python
Solution 1
def generate_nothing():
return
yield
Solution 2
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
def generate_nothing():
return iter([])
Solution 4
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
Sonic Lee
Updated on December 06, 2020Comments
-
Sonic Lee over 3 years
According to answer to this question,
yield break
in C# is equivalent toreturn
in Python. In the normal case,return
indeed stops a generator. But if your function does nothing butreturn
, you will get aNone
not an empty iterator, which is returned byyield 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 runyield
beforereturn
, 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?