为什么嵌套 "yield from" 语句(生成器委托)会产生终止值 `None`?
Why does nesting "yield from" statements (generator delegation) produce terminating `None` value?
是否可以嵌套 yield from
语句?
简单的形式很明显:
def try_yield1():
x = range(3)
yield from x
产生:
0
1
2
但是如果我有嵌套的生成器呢?
def try_yield_nested():
x = [range(3) for _ in range(4)]
yield from ((yield from y) for y in x)
这会产生:
0
1
2
None # why?
0
1
2
None # ...
0
1
2
None # ...
如果我使用 yield from
(即使它是嵌套的),为什么会产生 None
?
我知道我可以做类似的事情:
from itertools import chain
def try_yield_nested_alternative():
x = [range(3) for _ in range(4)]
yield from chain.from_iterable(x)
产生相同的输出,但不包括 None
(这是我所期望的)。我也可以写一个简单的循环:
for x in [range(3) for _ in range(3)]:
yield from x
但是,我认为使用嵌套委托会更像 Pythonic(甚至最好是 yield from x from y
或 yield from x for x in y
,但这不是正确的语法)。为什么它没有像我预期的那样工作?
yield
是一个表达式,它会计算你 send(value)
的任何值。简单地说,如果你什么都不发送,你会得到一个 None
输出,因为 yield
的值将是 None
.
yield from
本身等于 None
,而您正在使用其中两个。在第二个 yield from
中,您正在迭代一个列表,该列表使用该列表的项目输入生成器,但您还使用 yield from
到 return 那个生成器表达式,returns 列表及其本身在每次迭代时等效于 None
,因此为什么在范围的每次项目迭代后你得到一个 None
.
基本上这就是正在发生的事情:
(yield from y) for y in x
产生值 [0, 1, 2]
yield from
产生前一个的值,也产生前一个 yield from
的值,即 None
.
- 正在评估 [0, 1, 2],然后由于
(yield from y) for y in x
中的 yield from
而添加 None
。
不幸的是,由于表达式的性质,无法摆脱 None
输出。你最好使用 from_iterable
.
解释 yield 表达式的来源;
https://docs.python.org/2.5/ref/yieldexpr.html
是否可以嵌套 yield from
语句?
简单的形式很明显:
def try_yield1():
x = range(3)
yield from x
产生:
0
1
2
但是如果我有嵌套的生成器呢?
def try_yield_nested():
x = [range(3) for _ in range(4)]
yield from ((yield from y) for y in x)
这会产生:
0
1
2
None # why?
0
1
2
None # ...
0
1
2
None # ...
如果我使用 yield from
(即使它是嵌套的),为什么会产生 None
?
我知道我可以做类似的事情:
from itertools import chain
def try_yield_nested_alternative():
x = [range(3) for _ in range(4)]
yield from chain.from_iterable(x)
产生相同的输出,但不包括 None
(这是我所期望的)。我也可以写一个简单的循环:
for x in [range(3) for _ in range(3)]:
yield from x
但是,我认为使用嵌套委托会更像 Pythonic(甚至最好是 yield from x from y
或 yield from x for x in y
,但这不是正确的语法)。为什么它没有像我预期的那样工作?
yield
是一个表达式,它会计算你 send(value)
的任何值。简单地说,如果你什么都不发送,你会得到一个 None
输出,因为 yield
的值将是 None
.
yield from
本身等于 None
,而您正在使用其中两个。在第二个 yield from
中,您正在迭代一个列表,该列表使用该列表的项目输入生成器,但您还使用 yield from
到 return 那个生成器表达式,returns 列表及其本身在每次迭代时等效于 None
,因此为什么在范围的每次项目迭代后你得到一个 None
.
基本上这就是正在发生的事情:
(yield from y) for y in x
产生值 [0, 1, 2]yield from
产生前一个的值,也产生前一个yield from
的值,即None
.- 正在评估 [0, 1, 2],然后由于
(yield from y) for y in x
中的yield from
而添加None
。
不幸的是,由于表达式的性质,无法摆脱 None
输出。你最好使用 from_iterable
.
解释 yield 表达式的来源; https://docs.python.org/2.5/ref/yieldexpr.html