I was playing with generators a bit, when I suddenly wrote this piece of code.
Although I have written it, I don't know why it is valid, or why it works.
>>> x = (lambda : [(yield 1), (yield 2)])()
>>> next(x)
1
>>> next(x)
2
>>> next(x)
StopIteration
You created a generator function, with the lambda
syntax. yield
is just another expression, so can be used inside a lambda.
You basically did this:
def foo():
return [(yield 1), (yield 2)]
x = foo()
but all in a single expression.
Both yield
expressions return None
, so the StopIteration
result value is set to [None, None]
:
>>> x = (lambda : [(yield 1), (yield 2)])()
>>> next(x), next(x)
(1, 2)
>>> try:
... next(x)
... except StopIteration as si:
... print(si.value)
...
[None, None]
Instead of using next()
, you could use generator.send()
to make the yield
values return something other than None
:
>>> x = (lambda : [(yield 1), (yield 2)])()
>>> next(x) # advance to first yield
1
>>> x.send(42) # set return value for first yield, continue to second
2
>>> try:
... x.send(81) # set return value for second yield
... except StopIteration as si:
... print(si.value)
...
[42, 81]
It works, because it is legal Python syntax. It's not very useful however.