<p>在某些情况下,对于生成器,最好使用堆栈而不是递归。应该可以使用堆栈和while循环重写递归方法。</p>
<p>下面是一个递归方法的示例,该方法使用回调并可以使用堆栈逻辑重写:</p>
<pre><code>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)
</code></pre>
<p>上面的方法遍历一个节点树,其中每个节点都有一个<code>children</code>数组,该数组可能包含子节点。当遇到每个节点时,将发出回调并将当前节点传递给它。</p>
<p>方法可以这样使用,在每个节点上打印出一些属性。</p>
<pre><code>def callback(node):
print(node['id'])
traverse_tree(callback)
</code></pre>
<p><strong>改用堆栈并将遍历方法编写为生成器</strong></p>
<pre><code># 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 reversed(node.get('children', [])):
stack.append(child)
</code></pre>
<p>(请注意,如果希望与原来的遍历顺序相同,则需要反转子级的顺序,因为附加到堆栈的第一个子级将是最后一个子级。)</p>
<p>现在您可以获得与上面的<code>traverse_tree</code>相同的行为,但是使用生成器:</p>
<pre><code>for node in iternodes():
print(node['id'])
</code></pre>
<p>这不是一刀切的解决方案,但是对于某些生成器,用堆栈处理代替递归可能会得到一个很好的结果。</p>