Python Permutation Program Flow帮助

时间:2010-03-26 20:32:00

标签: python workflow recursion

我在activestate找到了这个代码,它需要一个字符串并打印字符串的排列。 我知道它是一个递归函数,但我真的不明白它是如何工作的,如果有人可以引导我完成程序流程,那就太好了,谢谢你们!

import sys

def printList(alist, blist=[]):
    if not len(alist): print ''.join(blist)
    for i in range(len(alist)):
        blist.append(alist.pop(i))
        printList(alist, blist)
        alist.insert(i, blist.pop())

if __name__ == '__main__':
    k = 'love'
    if len(sys.argv) > 1: k = sys.argv[1]
    printList(list(k))

3 个答案:

答案 0 :(得分:6)

您可以通过绘制递归树来了解printList的行为方式。每个节点由两个元素组成:alistblist。根目录包含alist,其中包含您要置换的项目的初始序列,以及空blist。 树的每个节点对该节点的alist的每个元素都有一个分支;通过从父亲的alist中选择一个元素,你从'父'节点移动到每个'子节点'并且:

  • 分配给孩子的alist父亲的alist 减去该元素;
  • 为孩子的blist分配父亲的blist以及附加在其末尾
  • 元素。

叶子有一个空的alist,并且由于遵循从根到叶子的不同路径,你必须以不同的顺序从根alist中选择元素,blist叶子本身包含根alist的所有各种排列。

例如([abc],[] == alist,blist):

                           [abc],[] 
                         /     |     \
                       a/     b|      \c
                       /       |       \
                  [bc],[a]  [ac],[b]   [ab],[c]
                  /     \
                b/       \c
                /         \
           [c],[ab]      [b],[ac]
              |             |
             c|             |b
              |             |
           [],[abc]      [],[acb]


def printList(alist, blist=[]):
    # if alist is empty, we are in a 'leaf' in the recursion tree;
    # then blist contains one permutation; print it
    if not len(alist): print ''.join(blist)

    # ELSE, for each possible position in alist,
    for i in range(len(alist)):

        # move the element at that position from alist to the end of blist
        blist.append(alist.pop(i))

        # go to the 'children' node and do the printing job for its subtree
        printList(alist, blist)

        # then move back the element from the end of blist to its original
        # position in alist, so we can continue with the for loop
        # without altering alist
        alist.insert(i, blist.pop())

答案 1 :(得分:3)

要理解它清楚地删除循环,使用alist = love和blist初始化为[]: for循环中的4个printlist调用现在将是(在递归的第一级):

   printList("ove","l");
   printList("lve","o");
   printList("loe","v");
   printList("lov","e");

这些printList调用中的每一个都将bList初始化为一个字母列表的所有可能排列,并且alist具有剩余的3个字母。这将继续,直到alist变空并且所有字母都是blist(并且打印发生if not len(alist): print ''.join(blist)

在第二级递归中,例如

   printList("ove","l") will result in 3 calls

   printList("ve","lo");
   printList("oe","lv");
   printList("ov","le");

总排列= 4(第一级)* 3(第二级)* 2 * 1

答案 2 :(得分:0)

无耻插件 - 这是python中的基本排列代码以及我博客的解释。 Playing with recursion - string permutation