相当于Python生成器的`return`

时间:2014-04-12 20:59:50

标签: python coding-style generator yield

有时,当将递归函数重写为生成器时,我会忽略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,就是这样,所以退出函数”。有办法吗?

2 个答案:

答案 0 :(得分:7)

不要错过return,请使用它。

return之后可以yield

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

另一种方法是在两种情况下使用return,其中第一种情况返回长度为1的序列,第二种情况返回generator-expression:

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的限制。

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

答案 1 :(得分:5)

没有。当我写"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:陈述并继承其余的陈述。