正确使用扩展?

时间:2013-03-07 05:28:52

标签: python list tree extend

class BTNode(object):
"""A node in a binary tree."""

def __init__(self, item, left=None, right=None):
    """(BTNode, object, BTNode, BTNode) -> NoneType
    Initialize this node to store item and have children left and right,
    as well as depth 0.
    """
    self.item = item
    self.left = left
    self.right = right
    self.depth = 0  # the depth of this node in a tree

def __str__(self):
    """(BTNode) -> str
    Return a "sideways" representation of the subtree rooted at this node,
    with right subtrees above parents above left subtrees and each node on
    its own line, preceded by as many TAB characters as the node's depth.
    """
    # If there is a right subtree, add an extra TAB character in front of
    # every node in its string representation, with an extra newline at the
    # end (ready to be concatenated with self.item).
    if self.right:
        str_right = "\t" + str(self.right).replace("\n", "\n\t") + "\n"
    else:
        str_right = ""
    # The string representation of self.item: if item is a string, use
    # repr(item) so that quotes are included and special characters are
    # treated correctly -- just like in a list; else use str(item).
    if isinstance(self.item, str):
        str_item = repr(self.item)
    else:
        str_item = str(self.item)
    # If there is a left subtree, add an extra TAB character in front of
    # every node in its string representation, with an extra newline at the
    # beginning (ready to be concatenated with self.item).
    if self.left:
        str_left = "\n\t" + str(self.left).replace("\n", "\n\t")
    else:
        str_left = ""
    # Put the right subtree above the root above the left subtree.
    return str_right + str_item + str_left

def leaves_and_internals(self):
    """(BTNode) -> ([object], [object])
    Return a pair of lists: (list of all the items stored in the leaves of
    the subtree rooted at this node, list of all the items stored in the
    internal nodes of the subtree rooted at this node).
    """
    #Leaf: Doesn't have children
    #Internal Node: Has children
    leaf = []
    internal = []
    if not self.left and not self.right:
        leaf.append(self.item)
    if self.left is not None:
        internal.append(self.item)
        if self.right is not None:
            self.right.leaves_and_internals()
        self.left.leaves_and_internals()
    elif self.right is not None:
        internal.append(self.item)
        self.right.leaves_and_internals()
    print(leaf, internal)
    return leaf, internal

BTNode类是我们无法编辑的初学者代码。我的职责是按照给定的文档字符串为leaves_and_intervals编写代码。我目前唯一的问题是不知道如何使用extend来递归地正确组合列表。

我的测试块看起来像这样:

if __name__ == "__main__":
    root = BTNode(2, BTNode(4, BTNode(6, BTNode(8, None, None), None), None), None)
    root.leaves_and_internals()

我的输出看起来像这样:

[8] []
[] [6]
[] [4]
[] [2]

正确的输出应该如此(顺序无关紧要):

[8] [6, 4, 2]

如何正确使用extend,以便每次执行时叶子和内部都不会重置回空列表?我知道我必须有第二组扩展列表,只是不确定如何实现它。

2 个答案:

答案 0 :(得分:1)

如果要递归解决此问题,则无需显式声明空列表。 只需汇总每个子问题的结果。

这是我的方法:

def leaves_and_internals(self): 
    if not self.left and not self.right:
        #leaf.append(self.item)
        return ([], [self.item])
    if self.left is not None:
        #internal.append(self.item)
        if self.right is not None:
            #return ([self.item], []) + self.right.leaves_and_internals()
            return tuple(map(operator.add,([self.item], []), self.right.leaves_and_internals()))
        #return ( [self.item], []) + self.left.leaves_and_internals()
        return tuple( map(operator.add, ([self.item], []), self.left.leaves_and_internals()))
    elif self.right is not None:
        #internal.append(self.item)
        #(leaf, internal) + self.right.leaves_and_internals()
        #return ( [self.item], []) + self.right.leaves_and_internals()
        return tuple(map(operator.add,([self.item], []), self.right.leaves_and_internals()))

答案 1 :(得分:0)

我看到你的代码几乎有正确的逻辑。这是我的实施。

def leaves_and_internals(self):
    leaves    = []
    internals = []

    if self.left or self.right:
        internals.append(self.item)
    else:
        leaves.append(self.item)

    if self.left:
        sub_leaves, sub_internals = self.left.leaves_and_internals()
        leaves.extend(sub_leaves)
        internals.extend(sub_internals)

    if self.right:
        sub_leaves, sub_internals = self.right.leaves_and_internals()
        leaves.extend(sub_leaves)
        internals.extend(sub_internals)

    return leaves, internals