Looping through tree hierarchy in python?

本小妞迷上赌 提交于 2021-01-01 06:39:39

问题


I'm new here and pretty new to python!

We got a homework, and I already was able to do rest of it, but one problem remains: If I have a tree hierarchy like this:

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

And they are all instances of one class named TreeHierarchyClass, and they all have a name attribute, how can I find the one with name I input?

I tried to use for loops but there's no way to know how many I need? Getting the name is easy:

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

but how do I loop through the objects?


回答1:


You should use simple recursion here. The method depends a little on how your child objects are attached to the parent object.

This one works if they are in a list self.children, which I'd recommend to do. Just define the following method inside your class:

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

Edit: To make this work for any attribute, not just name, use getattr() instead:

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

And simply call root.findObjectByName("Sub Child!") or to use the second method: root.findObject("name", "Sub Child!")




回答2:


You can use recursion or you can use iteration. Either way does not matter. But you need a strategy to search the tree.

Here are some strategry to go through a graph:

  • http://en.wikipedia.org/wiki/Breadth-first_search
  • http://en.wikipedia.org/wiki/Depth-first_search

The main idea is to not go through the same node / leaf twice, which is trivial for trees, but that require coloring for graphs:

  • http://en.wikipedia.org/wiki/Graph_coloring

There are a few design patterns you can use, e.g. the visitor pattern, and you add a method .visit() to your TreeHierarchyClass to visit its sub-nodes and another one to find nodes by name.

  • http://en.wikipedia.org/wiki/Visitor_pattern

example:

# 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))

you can visit all the nodes with:

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)

let's build a sample tree structure:

root = TreeHierarchyClass(0)

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

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

now let's find some items:

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.')

this example will print:

>>> 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.


来源:https://stackoverflow.com/questions/13711187/looping-through-tree-hierarchy-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!