【问题标题】:Looping through tree hierarchy in python?循环遍历python中的树层次结构?
【发布时间】:2012-12-04 20:20:17
【问题描述】:

我是新来的,对 python 很陌生!

我们有一个作业,我已经能够完成其余的作业,但还有一个问题: 如果我有这样的树层次结构:

root = [
    parent1 = [
        child1,
        child2 = [
            sub_child
        ]
        child3
    ],
    parent2 = [
        child1,
        child2
    ]
]

它们都是一个名为TreeHierarchyClass的类的实例,并且它们都有一个name属性,如何找到我输入的那个名字?

我尝试使用 for 循环,但无法知道我需要多少个循环?取名字很简单:

name = input("Enter name: ")
if name == TreeHierarchyObject.name:
    print("Found it!")

但是如何循环遍历对象呢?

【问题讨论】:

  • root 是什么类型的对象? list? dict?我知道没有 Python 语法允许像您当前在示例中那样使用 root = [ parent = [ ... 之类的子声明。

标签: python recursion tree


【解决方案1】:

你应该在这里使用简单的递归。 该方法在一定程度上取决于您的子对象如何附加到父对象。

如果它们在 self.children 列表中,则此选项有效,我建议这样做。 只需在您的类中定义以下方法:

def findObjectByName(self, name):
    if self.name == name:
        return self
    else:
        for child in self.children:
            match = child.findObjectByName(name)
            if match:
                return match

编辑: 要使其适用于任何属性,而不仅仅是名称,请改用getattr()

def findObject(self, attr, value):
    if getattr(self, attr) == value:
        return self
    else:
        for child in self.children:
            match = child.findObject(attr, value)
            if match:
                return match

只需调用root.findObjectByName("Sub Child!") 或使用第二种方法:root.findObject("name", "Sub Child!")

【讨论】:

  • 谢谢,我用child而不是children,但我觉得儿童更好,改了!
【解决方案2】:

您可以使用recursion,也可以使用iteration。无论哪种方式都无所谓。但是你需要一个搜索树的策略。

以下是一些通过图表的策略:

主要思想是不要通过同一个节点/叶子两次,这对于树来说是微不足道的,但是对于图需要coloring

您可以使用一些设计模式,例如visitor 模式,然后将方法 .visit() 添加到 TreeHierarchyClass 以访问其子节点,并添加另一个方法以按名称查找节点。

示例:

# imagine we got this class
class TreeHierarchyClass(object):
    def __init__(self, value):
        self.children = []
        self.value = value
        if self.value == 13:
            self.name = 'the lucky one.'
    def add(self, value):
        self.children.append(type(self)(value))

您可以通过以下方式访问所有节点:

def visit(tree):
    visited = set()
    nonvisited = set()
    nonvisited.update(tree.children)
    while nonvisited:
        item = nonvisited.pop()
        # already seen
        if item in visited:
            continue
        # mark item
        visited.add(item)
        yield item
        # add children
        nonvisited.update(item.children)

让我们构建一个示例树结构:

root = TreeHierarchyClass(0)

for i in range(10):
    root.add(i)

for i in range(10):
    root.children[1].add(i + 10)

现在让我们找到一些项目:

def find(name):
    for item in visit(root):
        print 'checking item with value %d' % item.value,
        if getattr(item, 'name', None) == name:
            print '- found it.'
            break
        else:
            print '- nope, keep searching.'
    else:
        print 'Sorry, not found.'

find('the lucky one.')
find('the lost one.')

这个例子将打印出来:

>>> find('the lucky one.')
checking item with value 7 - nope, keep searching.
checking item with value 0 - nope, keep searching.
checking item with value 1 - nope, keep searching.
checking item with value 12 - nope, keep searching.
checking item with value 2 - nope, keep searching.
checking item with value 9 - nope, keep searching.
checking item with value 19 - nope, keep searching.
checking item with value 3 - nope, keep searching.
checking item with value 11 - nope, keep searching.
checking item with value 4 - nope, keep searching.
checking item with value 14 - nope, keep searching.
checking item with value 5 - nope, keep searching.
checking item with value 6 - nope, keep searching.
checking item with value 15 - nope, keep searching.
checking item with value 8 - nope, keep searching.
checking item with value 16 - nope, keep searching.
checking item with value 13 - found it.
>>> find('the lost one.')
checking item with value 7 - nope, keep searching.
checking item with value 0 - nope, keep searching.
checking item with value 1 - nope, keep searching.
checking item with value 12 - nope, keep searching.
checking item with value 2 - nope, keep searching.
checking item with value 9 - nope, keep searching.
checking item with value 19 - nope, keep searching.
checking item with value 3 - nope, keep searching.
checking item with value 11 - nope, keep searching.
checking item with value 4 - nope, keep searching.
checking item with value 14 - nope, keep searching.
checking item with value 5 - nope, keep searching.
checking item with value 6 - nope, keep searching.
checking item with value 15 - nope, keep searching.
checking item with value 8 - nope, keep searching.
checking item with value 16 - nope, keep searching.
checking item with value 13 - nope, keep searching.
checking item with value 17 - nope, keep searching.
checking item with value 10 - nope, keep searching.
checking item with value 18 - nope, keep searching.
Sorry, not found.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    • 2016-09-09
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    相关资源
    最近更新 更多