【问题标题】:How to iterate through instances in a tree?如何遍历树中的实例?
【发布时间】:2016-10-16 16:27:08
【问题描述】:

我在python中自己编写的树类有问题:

class Tree:
    def __init__(self, parent=0, value=0):
        self.value = value
        self.parent = parent
    def __iter__(self): return self
    def next(self):
        tmp = self.value
        try:
            self.parent = self.parent.parent
            self.value = self.parent.value
        except AttributeError:
            raise StopIteration
        return tmp
    def sum(self):
        list_ = [item for item in self]
        print list_
        return sum(list_)

其实“树”还没有写完整,只是当前的问题阻碍了进一步的进展。 该结构只有两个实例变量(valueparent)。 我想用迭代器将当前实例的值与第一个父级相加(如果可能的话)。 sum 方法用于此(额外的list_ 变量是不必要的,但有助于进一步解释问题)。

运行测试用例时

parent = Tree()
child = Tree(parent=parent, value=8)
child2 = Tree(parent=child,value=10)
print child2.sum()

我得到以下信息:

[10]
10

请问,谁能解释为什么值列表只包含一个数字,尽管它应该看起来像[10,8]?似乎问题出在<strong>iter</strong>next的实现中,但我不明白如何修复解决方案。

提前谢谢你。

【问题讨论】:

  • item for item in self 只会返回 self。迭代需要跟随 self.parent 直到它是 None ,它只发生在根节点 - 你可能需要一个 yield 来做到这一点。此外,init 定义中的 parent 和 value 的默认值必须使用 None 而不是 0 作为默认值。此外,您不是在构建树,这是由父项链接的项目列表。为了正确实现树,每个节点不应该包含 child1/child2(或左/右)实例变量,以便结构可以从根导航到它吗?
  • 致@barny:我完全同意您关于None 作为主要父母的看法。这棵树也应该包含孩子,但在我的情况下可能有很多孩子。正如我所写的,由于迭代器的问题,此功能尚未实现。最后,遍历 self.parent 是一个好主意,尽管我无法很好地实现它。如果next 返回self.parent(即使是self = self.parent),sum 可以预见地陷入无休止的循环。如果你想用yield 展示一个实现。这可能会有很大帮助。

标签: python python-2.7


【解决方案1】:

我不确定您是否可以将此称为Tree。人们会期望父节点和多个叶节点,而不仅仅是对象的线性连接。

见:A general tree implementation?

另一方面,如果您想实现链表,应考虑 Barny 在对您的问题的评论中提出的建议,您也可以关注:Python Linked List

在您当前的实现中,您需要某种循环,从当前子节点一直走到头父节点。并且当没有找到下一个父属性时,停止迭代。下面将逻辑放在类的__iter__方法中,现在是生成器函数:

class Tree:
    def __init__(self, parent=None, value=0):
        self.value = value
        self.parent = parent

    def __iter__(self): 
        _parent = self.parent
        yield self.value
        while True:
            try:               
                yield _parent.value 
                _parent = _parent.parent
            except AttributeError:
                break  

    def sum_from_node(self):
        list_ = [item for item in self]
        print list_
        return sum(list_)

演示:

parent = Tree()
child = Tree(parent=parent, value=8)
child2 = Tree(parent=child,value=10)
child3 = Tree(parent=child2,value=4)
print child3.sum_from_node()
# [4, 10, 8, 0]
# 22

【讨论】:

    【解决方案2】:

    给你:

    class Tree:
        def __init__(self, parent=None, value=0):
            self.value = value
            self.parent = parent
    
        def __iter__(self): 
            yield self.value
            root = self
            while root.parent is not None:
                yield root.parent.value
                root = root.parent
            raise StopIteration
    
    
        def tree_sum(self):
            return sum(list(self))
    
    
    parent = Tree()
    child = Tree(parent=parent, value=8)
    child2 = Tree(parent=child,value=10)
    

    我已将默认 parent 值更改为无。

    for i in child2:
        print(i)
    
    10
    8
    0 # 0 is here because the parent value is 0 by default.
    

    【讨论】:

    • 每次迭代类的实例时,您都在构建一个列表。随着父母人数的增加,这可能是不可取的
    猜你喜欢
    • 2018-08-17
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 2014-04-03
    相关资源
    最近更新 更多