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。