recursion使用yield

有什么方法可以混合recursion和yield语句吗? 例如,一个无限数量的生成器(使用recursion)会是这样的:

 def infinity(start): yield start # recursion here ... >>> it = infinity(1) >>> next(it) 1 >>> next(it) 2 

我试过了:

 def infinity(start): yield start infinity(start + 1) 

 def infinity(start): yield start yield infinity(start + 1) 

但他们都没有做我想要的,第一个停止后,它start ,第二个start ,然后发电机,然后停下来。

注:请,我知道你可以使用while循环来做到这一点:

 def infinity(start): while True: yield start start += 1 

我只是想知道这是否可以recursion地完成。

是的,你可以这样做:

 def infinity(start): yield start for x in infinity(start + 1): yield x 

一旦达到最大recursion深度,这将会出错。

从Python 3.3开始,你将可以使用

 def infinity(start): yield start yield from infinity(start + 1) 

如果您只是recursion地调用您的生成器函数而不循环或者yield from它生成,您所做的只是构build一个新的生成器,而不实际运行函数体或产生任何东西。

进一步的细节见PEP 380 。

在某些情况下,最好使用堆栈而不是recursion生成器。 应该可以使用堆栈和while循环重写recursion方法。

下面是一个使用callback的recursion方法的示例,可以使用堆栈逻辑重写:

 def traverse_tree(callback): # Get the root node from somewhere. root = get_root_node() def recurse(node): callback(node) for child in node.get('children', []): recurse(child) recurse(root) 

上述方法遍历节点树,其中每个节点都有一个可能包含子节点的children数组。 当遇到每个节点时,发出callback,并将当前节点传递给它。

该方法可以这样使用,在每个节点上打印出一些属性。

 def callback(node): print(node['id']) traverse_tree(callback) 

使用堆栈,并将其作为生成器写入遍历方法

 # A stack-based alternative to the traverse_tree method above. def iternodes(): stack = [get_root_node()] while stack: node = stack.pop() yield node for child in node.get('children', []): stack.append(child) 

现在,您可以获得与上面的traverse_tree相同的行为,但使用一个生成器:

 for node in iternodes(): print(node['id']) 

这不是一个通用的解决scheme,但是对于某些生成器,您可能会得到一个很好的结果来代替recursion堆栈处理。

所以基本上你只需要在你需要recursion调用你的函数的地方添加一个for循环。 这适用于Python 2.7。