【问题标题】:Why is no value returned from my generator?为什么我的生成器没有返回值?
【发布时间】:2018-05-29 14:22:12
【问题描述】:

我在 Python 生成器中遇到了一些令人惊讶的行为:

>>> def f(n):
...     if n < 2:
...         return [n]
...     for i in range(n):
...         yield i * 2
... 
>>> list(f(0))
[]
>>> list(f(1))
[]
>>> list(f(2))
[0, 2]

为什么前两种情况生成器没有返回值?

【问题讨论】:

标签: python python-3.x generator


【解决方案1】:

因为生成器return 语句不返回任何内容,它们会结束执行(python 知道这是一个生成器,因为它至少包含一个yield 语句)。而不是return [n]

 yield n
 return

编辑

在向 python 核心开发人员提出这个问题后,他们将我指向 python docs,上面写着

在生成器函数中,return 语句表明生成器已完成并将引发 StopIteration。返回的值(如果有)用作构造 StopIteration 的参数,并成为 StopIteration.value 属性。

所以你可以这样做

def f(n):
    if n < 2:
         return [n]
    for i in range(n):
         yield i * 2

g = f(1)
res = []
while True:
    try:
         res.append(next(g))
    except StopIteration as e:
         if e.value is not None:
              res = e.value
         break

如果你真的,真的想要。

【讨论】:

  • 最好添加一个文档链接,说明 return 的值在生成器中被忽略。
  • 公平地说,我认为这是无证行为。为什么在生成器中使用return n 不是SyntaxError,这超出了我的理解。这个PEP 没有描述任何关于return n 的内容。编辑:实际上,它就在bottom。它仍然只是说它是不允许的,而不是它默默地失败。
【解决方案2】:

return 不会生成 iterator。使用yield,然后使用return

def f(n):
        if n < 2:
            yield n
            return
        for i in range(n):
            yield i * 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 2013-04-23
    相关资源
    最近更新 更多