 <p>At each terminal node (leaf) you are printing <code>)</code>s for all parents; you should only do so for <em>consecutive right-side</em> parents.</p> <p>I suggest renaming <code>parents</code> to <code>depth</code> and adding a <code>right_depth</code> parameter.</p> <p><strong>Edit:</strong> after playing around with it a bit, I decided it was better to delegate it to the tree:</p> <pre><code>class Node: INDENT = " " __slots__ = ["lhs", "word_label", "left_child", "right_child"] def __init__(self, lhs, *args): self.lhs = lhs num_args = len(args) if num_args == 1: self.word_label = args[0] self.left_child = None self.right_child = None elif num_args == 2: self.word_label = None self.left_child = args[0] self.right_child = args[1] else: raise ValueError("should have one arg (word_label: str) or two args (left: Node and right: Node)") def is_terminal(self): return self.word_label is not None def tree_str(self, depth=0, indent=None): if indent is None: indent = self.INDENT if self.is_terminal(): return "\n{}({} '{}' )".format( indent * depth, self.lhs, self.word_label ) else: return "\n{}( {}{}{} )".format( indent * depth, self.lhs, self.left_child .tree_str(depth + 1, indent), self.right_child.tree_str(depth + 1, indent) ) def __str__(self): return self.tree_str() </code></pre> <p>then some syntactic helpers,</p> <pre><code>def make_leaf_type(name): def fn(x): return Node(name, x) fn.__name__ = name return fn for leaf_type in ("VB", "DT", "NNS", "IN", "NP_NNP", "TO", "NN", "PUNC"): locals()[leaf_type] = make_leaf_type(leaf_type) def make_node_type(name): def fn(l, r): return Node(name, l, r) fn.__name__ = name return fn for node_type in ("TOP", "S_VP", "NP", "PP"): locals()[node_type] = make_node_type(node_type) </code></pre> <p>so I can create the tree,</p> <pre><code>tree = \ TOP( S_VP( VB('List'), NP( NP( DT('the'), NNS('flights') ), PP( PP( IN('from'), NP_NNP('Baltimore') ), PP( TO('to'), NP( NP_NNP('Seattle'), NP( NP( DT('that'), NN('stop') ), PP( IN('in'), NP_NNP('Minneapolis') ) ) ) ) ) ) ), PUNC('.') ) </code></pre> <p>which then prints like</p> <pre><code>&gt;&gt;&gt; print(tree) ( TOP ( S_VP (VB 'List' ) ( NP ( NP (DT 'the' ) (NNS 'flights' ) ) ( PP ( PP (IN 'from' ) (NP_NNP 'Baltimore' ) ) ( PP (TO 'to' ) ( NP (NP_NNP 'Seattle' ) ( NP ( NP (DT 'that' ) (NN 'stop' ) ) ( PP (IN 'in' ) (NP_NNP 'Minneapolis' ) ) ) ) ) ) ) ) (PUNC '.' ) ) </code></pre> <p>which I believe is <em>actually</em> what is desired.</p>