递归函数中的“不在函数中”错误

时间:2015-04-19 05:21:02

标签: python function recursion tree

我正在编写一个算法来计算树所拥有的节点总数。这是代码:

def tree_nodes(tree):
    """Given a tree, returns the total amount of nodes it has."""
    def recursive_node_count(node):
        """Recursive count function."""
        childs = tree[node]
        if childs == None:
            return 1
        else:
            nodes_so_far = 0
            for i in xrange(len(childs)):
                nodes_in_this_branch = recursive_node_count(childs[i])
                nodes_so_far += nodes_in_this_branch          
            return nodes_so_far

    root = tree['root']
    total_nodes = recursive_node_count(root)
    return total_nodes

tree基本上是列表字典。例如:

tree = {0: [1], 1: [2], 2: [3, 4], 3: None, 4: None, 'root': 0}

enter image description here

当我尝试运行我的代码时,这是我收到的输出:

at Answer.py. not in a function on line 31
at Answer.py. in recursive_node_count on line 31
at Answer.py. in recursive_node_count on line 31
at Answer.py. in recursive_node_count on line 31
at Answer.py. in recursive_node_count on line 31
at Answer.py. in recursive_node_count on line 31
at Answer.py. in recursive_node_count on line 31
at Answer.py. in recursive_node_count on line 31
at Answer.py. in recursive_node_count on line 31
at Answer.py. in recursive_node_count on line 31
at Answer.py. in tree_nodes on line 36
at Answer.py. in <module> on line 96

这些是原始代码中的行31(在函数定义内),36(在定义内)和96(对定义的调用):

31: nodes_in_this_branch = recursive_node_count(childs[i])
36: total_nodes = recursive_node_count(root)
96: nodes = tree_nodes(tree)

我检查了语法,缩进,制表符,空格,但我找不到错误。我是Python的初学者。你能帮助我吗?

3 个答案:

答案 0 :(得分:2)

您当前的代码存在2个问题,

  1. 您目前不计算根节点
  2. 当没有孩子时你返回1,在这种情况下你应该返回0。我们同样需要计算每个级别的孩子数量,因此应该根据孩子的长度来初始化nodes_so_far。列表
  3. 纠正这些,该功能变为:

    def tree_nodes(tree):
        """Given a tree, returns the total amount of nodes it has."""
        def recursive_node_count(node):
            """Recursive count function."""
            childs = tree[node]
            if childs == None:
                return 0 # There are no child so return 0 in base case
            else:
                nodes_so_far = len(childs) # set to number of nodes passed
                for i in xrange(len(childs)):
                    nodes_in_this_branch = recursive_node_count(childs[i])
                    nodes_so_far += nodes_in_this_branch          
                return nodes_so_far
        root = tree['root']
        total_nodes = 1 + recursive_node_count(root) # Add 1 to count the root node
        return total_nodes
    

    在干运行中,这给出了输出:

    >>> tree = {0: [1], 1: [2], 2: [3, 4], 3: None, 4: None, 'root': 0}
    >>> tree_nodes(tree)
    5
    

答案 1 :(得分:2)

你的答案遗漏了几件事。这是围绕代码编写的固定版本:

def tree_nodes(tree):
    def recursive_node_count(node):
        if node is None:
            return 0
        total_nodes = 1
        if tree[node]:
            for child in tree[node]:
                if child:
                    total_nodes += recursive_node_count(child)
        return total_nodes

    root = tree['root']
    total_nodes = recursive_node_count(root)
    return total_nodes

>>> tree = {0: [1], 1: [2], 2: [3, 4], 3: None, 4: None, 'root': 0}
>>> print tree_nodes(tree)
5

答案 2 :(得分:1)

根据您提供的代码,我无法重现错误。语法上没有任何问题,确实运行良好。如果你能更深入地了解你所得到的错误,我会编辑我的答案。

话虽如此,如mu所述,此代码将返回错误数量的节点。具体来说,它将返回树的叶数,因为如果它没有任何子节点,您只计算当前节点。可以通过将nodes_so_far初始化为表示当前节点的1来解决此问题。

作为建议,您可能希望将for in xrange python语句切换为普通for in语句。 for in语句遍历列表,因此您不必使用索引号索引回列表。

下面的代码说明了这些变化。即使在只有一个节点且是根节点的情况下,此代码也将始终输出正确数量的节点。

def tree_nodes(tree):
    """Given a tree, returns the total amount of nodes it has."""
    def recursive_node_count(node):
        """Recursive count function."""
        childs = tree[node]
        if not childs:
            # Return 1 for the current node.
            return 1
        else:
            # Initialize to 1 to count the current node.
            nodes_so_far = 1
            # Python for in statement
            for child in childs:
                nodes_for_child = recursive_node_count(child)
                nodes_so_far += nodes_for_child
            return nodes_so_far
    root = tree['root']
    total_nodes = recursive_node_count(root)
    return total_nodes

print(tree_nodes(tree={0: [1], 1: [2], 2: [3, 4], 3: None, 4: None, 'root': 0}))
print(tree_nodes(tree={0: None, 'root': 0}))