【问题标题】:Building a generator from a recursive algorithm从递归算法构建生成器
【发布时间】:2012-10-24 21:44:55
【问题描述】:

我有一个递归方法,用于遍历一棵红黑树,并存储各种节点信息(在列表storage 中)。

def _walk (self, storage, func, starting_node) :
    if starting_node is not self._nil :
        self._walk(storage, func, starting_node.left)
        storage.append(func(starting_node))
        self._walk(storage, func, starting_node.right)

但是,我想重新实现这个方法,以便它构建一个生成器(据我了解,这应该可以节省时间和内存)。这样做的“最佳”方式是什么?

【问题讨论】:

  • 我认为它不会为您节省太多 - 除非您打算将存储作为生成器而不是列表。
  • gnibbler,这正是我的意思。感谢您让我澄清。

标签: python recursion iterator generator


【解决方案1】:

首先将动作与步行分离

def _walk (self, starting_node) :
    if starting_node is not self._nil :
        for x in self._walk(starting_node.left):
            yield x
        yield starting_node
        for x in self._walk(starting_node.right):
            yield x

def traverse(self):
    starting_node = ???     # maybe these are passed as
    func = ???              # parameters to traverse
    for node in self._walk(starting_node):
        yield func(node)

traverse 大致相当于

imap(func, self._walk(starting_node))

或者这个生成器表达式

(func(x) for x in self._walk(starting_node))

您可以通过手动优化尾递归来减少使用的堆栈量

def _walk (self, starting_node) :
    while starting_node is not self._nil :
        for x in self._walk(starting_node.left):
            yield x
        yield starting_node
        starting_node = starting_node.right

【讨论】:

  • 如果我没记错的话,递归调用 _walk 不会产生任何结果。
  • @thg435,你没记错 - 已修复。
【解决方案2】:
def _walk (self, func, starting_node) :
    if starting_node is not self._nil :
        for x in self._walk(func, starting_node.left) :
            yield x
        yield func(starting_node)
        for x in self._walk(func, starting_node.right) :
            yield x

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-25
    • 2017-08-01
    • 2020-12-09
    • 1970-01-01
    • 2014-04-07
    • 2010-09-24
    • 1970-01-01
    相关资源
    最近更新 更多