Lets say i have this tree:
cough
Yes / \\ No
sneezing
Here's what I came up with
class Tree:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
@property
def is_leaf(self):
return not (self.left or self.right)
def __repr__(self):
return 'Tree({}, {}, {})'.format(self.data, self.left, self.right)
def find(self, target, path_to=()):
if self.is_leaf:
if self.data == target:
yield path_to
else:
if self.left:
yield from self.left.find(target, (*path_to, True))
if self.right:
yield from self.right.find(target, (*path_to, False))
t = Tree('Cough', Tree('Sneezing', Tree('Fever', Tree('Dead'), Tree('Cold')), Tree('Fever', Tree('Influenza'), Tree('Cold'))), Tree('Sneezing', Tree('Fever', Tree('Dead'), Tree('Influenza')), Tree('Fever', Tree('Cold'), Tree('Healthy'))))
print(list(t.find('Influenza')))
By having our find
method be a generator, we can easily bubble positive results up the call stack using yield from
. If you're using a version of Python that doesn't support argument unpacking (*path_to, True)
, then path_to + (True,)
is equivalent
Edit: Here's a version the doesn't use yield
def find(self, target, path_to=()):
if self.is_leaf:
if self.data == target:
return [path_to]
else:
return []
else:
if self.left:
l = self.left.find(target, (*path_to, True))
if self.right:
r = self.right.find(target, (*path_to, False))
return l + r