【问题标题】:Why does nesting "yield from" statements (generator delegation) produce terminating `None` value?为什么嵌套“yield from”语句(生成器委托)会产生终止的“无”值?
【发布时间】:2017-09-09 03:41:34
【问题描述】:

是否可以嵌套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 yyield from x for x in y,但这不是正确的语法)。为什么它没有按我的预期工作?

【问题讨论】:

    标签: python python-3.x generator yield yield-from


    【解决方案1】:

    yield 是一个表达式,它会计算你send(value) 它的任何值。简单地说,如果你什么都不发送,你会得到一个None 输出,因为yield 的值是None

    yield from 本身等于None,而您正在使用其中的两个。在第二个yield from 处,您正在迭代一个列表,该列表使用该列表的项目输入生成器,但您还使用yield from 返回该生成器表达式,该表达式返回列表及其本身,这相当于None 在每次迭代中,因此为什么在每次迭代范围后你会得到一个 None

    基本上这就是正在发生的事情:

    1. (yield from y) for y in x 产生值 [0, 1, 2]
    2. yield from 产生前一个值,以及 yield from 前一个值,即 None
    3. 求值到 [0, 1, 2],然后在 (yield from y) for y in x 中添加 None,因为 yield from

    不幸的是,由于表达式的性质,没有办法摆脱None 输出。你最好使用from_iterable

    解释产量表达式的来源; https://docs.python.org/2.5/ref/yieldexpr.html

    【讨论】:

      猜你喜欢
      • 2015-01-14
      • 2020-04-07
      • 1970-01-01
      • 2020-05-30
      • 2016-12-02
      • 2020-05-25
      • 1970-01-01
      • 2018-01-23
      • 1970-01-01
      相关资源
      最近更新 更多