问题
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