【问题标题】:Equivalent of `return` for Python generatorsPython 生成器的 `return` 等价物
【发布时间】:2014-05-26 23:50:58
【问题描述】:

有时,在将递归函数重写为生成器时,我会怀念return 的简洁性。

"""
Returns a list of all length n strings that can be made out of a's and/or b's.
"""
def ab_star(n):
    if n == 0:
        return [""]

    results = []
    for s in ab_star(n - 1):
        results.append("a" + s)
        results.append("b" + s)

    return results

变成

"""
Generator for all length n strings that can be made out of a's and/or b's.
"""
def ab_star(n):
    if n == 0:
        yield ""

    else:
        for s in ab_star(n - 1):
            yield "a" + s
            yield "b" + s

else 困扰着我。我希望有办法说“yield,就是这样,所以退出函数”。有什么办法吗?

【问题讨论】:

  • 第一次使用yield后为什么不加一个return

标签: python coding-style generator yield


【解决方案1】:

不要错过return,使用它。

您可以在yield 之后立即return

def ab_star(n):
    if n == 0:
        yield ""
        return
    for s in ab_star(n - 1):
        yield "a" + s
        yield "b" + s

另一种方法是在两种情况下都使用return,其中第一种情况返回长度为 1 的序列,第二种情况返回生成器表达式:

def ab_star(n):
    if n == 0:
        return ( "", )
    return ( c+s for s in ab_star(n - 1) for c in 'ab' )

这种对yield 的避免避免了不能在同一个函数中同时使用return <value>yield 的限制。

(这适用于您的情况,因为您的函数必须是生成器。由于您只迭代结果,它也可以返回一个元组。)

【讨论】:

    【解决方案2】:

    没有。当我写"Simple Generators PEP" 时,我注意到:

    Q. Then why not allow an expression on "return" too?
    
    A. Perhaps we will someday.  In Icon, "return expr" means both "I'm
       done", and "but I have one final useful value to return too, and
       this is it".  At the start, and in the absence of compelling uses
       for "return expr", it's simply cleaner to use "yield" exclusively
       for delivering values.
    

    但这从未引起关注。在它出现之前;-),您可以通过将第一部分编写为使您的生成器看起来更像您的第一个函数:

    if n == 0:
        yield ""
        return
    

    然后您可以删除else: 语句并删除其余部分。

    【讨论】:

    • 哦,有趣。从this answer 看起来像return <expr> 现在实际上意味着不同的东西。所以我猜这永远不会发生?
    • 是的,在 3.3 return <expr> 中,生成器内部获得了一个含义,但是一个与产生值无关的非常模糊的含义。相反,它与StopIteration 异常有关,正如您链接到的答案所指出的那样。
    猜你喜欢
    • 1970-01-01
    • 2011-07-23
    • 2015-09-06
    • 2015-02-23
    • 2010-11-28
    • 2014-03-08
    • 2012-06-24
    • 1970-01-01
    相关资源
    最近更新 更多