【问题标题】:Python generators: correct code recursing a treePython生成器:递归树的正确代码
【发布时间】:2011-11-29 20:44:15
【问题描述】:
class Node(object):
    def __init__(self, lst):
        if type(lst) == list:
            self.value = lst[0]
            self.children = lst[1:]
        else:
            self.value = lst
            self.children = []
    @property
    def ChildElements(self):
        return [Node(a) for a in self.children]

    @property
    def GetValue(self):
        return self.value

def node_recurse_generator(node):
    yield node.value
    for n in node.ChildElements:
        node_recurse_generator(n)

Node 是一个简单的树状数据结构。列表的第一个元素始终是 Node 的值,后面的元素将是子元素。如果 Node 使用列表以外的其他内容启动,则该值将是 that,而 children 将是 [],一个空列表。

a = Node([1,[10,20,30],[100,200,300]])
>>> list(node_recurse_generator(a))
[1]

现在,对所有元素都有一个递归迭代器会很棒,但我的生成器只产生第一个元素。为什么会这样?

【问题讨论】:

  • 但是请注意,您构建树的方式容易出错:以下代码演示了这一点:b = [1,2,3]a = [0,b]n = Node(a)print(list(node_recurse_generator(n)))print(list(node_recurse_generator(n)))a[0] = 7 # does not affect nb[2] = 4 # affects nprint(list(node_recurse_generator(n))) b = [100,200,300] # from here on, changes in b no longer affect nprint(list(node_recurse_generator(n)) )

标签: python recursion generator


【解决方案1】:

仅递归调用 node_recurse_generator 是不够的 - 你必须 yield 其结果:

def node_recurse_generator(node):
    yield node.value
    for n in node.ChildElements:
        for rn in node_recurse_generator(n):
            yield rn

【讨论】:

  • 附带说明,这就是yield from 表达式(计划包含在 Python 3.3 中)将提供帮助的内容。参见 PEP 380:python.org/dev/peps/pep-0380
【解决方案2】:

正如置顶答案的评论中提到的yak,在Python 3.3之后也可以使用yield from

def node_recurse_generator(node):
    yield node.value
    for n in node.ChildElements:
        yield from node_recurse_generator(n)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-22
    • 2016-05-03
    • 1970-01-01
    • 2012-05-03
    • 2021-01-11
    • 2022-11-14
    • 2018-02-06
    • 2013-09-16
    相关资源
    最近更新 更多