print_parts()函数如何在编写程序第2.3章中起作用

时间:2015-04-07 01:30:58

标签: python tree partition-problem

在书籍编写程序chapter 2.3中,有一个函数print_part()让我感到困惑(整个代码here):

>>> def print_parts(tree, partition=[]):
        if is_leaf(tree):
            if root(tree):
                print(' + '.join(partition))
        else:
            left, right = branches(tree)
            m = str(root(tree))
            print_parts(left, partition + [m])
            print_parts(right, partition)

>>> print_parts(partition_tree(6, 4))
4 + 2
4 + 1 + 1
3 + 3
3 + 2 + 1
3 + 1 + 1 + 1
2 + 2 + 2
2 + 2 + 1 + 1
2 + 1 + 1 + 1 + 1
1 + 1 + 1 + 1 + 1 + 1

此函数打印使用最多4个部分到分区6的所有方法。我已经理解分区算法在partition_tree()中是如何工作的,并且理解分区树没有问题:

                   4
       _________________________
       |                       |
       4                       3
   _______                    _____
   |     |                    |    |
   ..   ...                ...    ...

但我仍然不知道如何从分区树中打印分区方式。特别是这些行:

print(' + '.join(partition))

print_parts(left, partition + [m])
print_parts(right, partition)
# why call twice? and the recursion here didn't looks like the
# way the print_parts() called in the beginning.

更新

  

这里的递归看起来不像print_parts()在开头调用的方式。

以一个更简单的args为例来说明我的困惑:

>>> print_parts(partition_tree(3, 2))
2 + 1
1 + 1 + 1

分区树是:

                         2
           --------------------------------
          2                               1
    ----------------           ------------------------
   F               1           1                     F
               ------        ------------
              T    F         1          F
                           -------
                          T      F

[2, [2, [False], [1, [True], [False]]], [1, [1, [1, [True], [False]],[False]],[False]]]

上面的列表首先传入func print_parts()作为树的值。

走到这一行:

print_parts(left, partition + [m])

左边的值是

[[2, [False], [1, [True], [False]]], [1, [1, [1, [True], [False]],[False]],[False]]]

它不再是树,因为在定义中树应该具有如下结构:[node, [branch],[branch]]。如果是这样,递归就行不通。

1 个答案:

答案 0 :(得分:1)

听起来你理解算法但可能不是Python代码。

print(' + '.join(partition))只是将列表格式化为您看到的输出格式。例如,它将列表[3, 2, 1]转换为字符串'3 + 2 + 1'

然后,print_parts的方式可以被调用的方式是"看起来不一样"因为原始调用是方法定义允许可选的第二个参数。如果未明确提供第二个选项,则默认情况下将其设置为空列表。这是函数定义中partition=[]的作用。

至于它为什么被称为"两次",它只是在递归的每一步,我们分支到两个分支(左和右) ,然后递归处理左侧和右侧。

更新(回复您的更新):

混淆源于这一行,Python可以同时分配多个变量:

left, right = branches(tree)

由于branches(tree)是长度为2的列表,因此2个元素分别分配给leftright

所以你说的不是真的:

  

左边的值是

[[2, [False], [1, [True], [False]]], [1, [1, [1, [True], [False]],[False]],[False]]]

但相反:

left, right = branches(partition_tree(3, 2))
print left
> [2, [False], [1, [True], [False]]]
print right
> [1, [1, [1, [True], [False]], [False]], [False]]