I want my Binary tree to be iterable so that I can loop though it to visit every node once. Also, inorder
is a generator function which returns the Iterator
and hence satisfies the Iterable
contract. But my code below instead of yielding every node just yields root node which in this case is A
. What I am doing wrong?
from collections import namedtuple
Node = namedtuple('Node', 'data, left, right')
root = Node('A',
Node('B', Node('D', None, None), Node('E', None, None)),
Node('C', None, Node('F', None, None)))
class BinaryTree(object):
def __init__(self, root=None):
self.root = root
def __iter__(self):
return self.inorder(self.root)
def inorder(self, node):
if node is None:
return
if node.left is not None:
self.inorder(node.left)
yield node
if node.right is not None:
self.inorder(node.right)
bt = BinaryTree(root)
for node in bt:
print node.data
The problem is that you call self.inorder(node.left)
, but don't do anything with the result, and as a result, the code is simply executed (well executed lazily, which means not executed), and the runtime environment continues to the next line.
You need to resolve it by propagating (ie re-yielding ) the elements that are generated by the calls to inorder
:
def inorder(self, node):
if node is None:
return
if node.left is not None:
for x in self.inorder(node.left) :
# you need to *re-yield* the elements of the left and right child
yield x
yield node
if node.right is not None:
for x in self.inorder(node.right) :
yield x
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.