以字典顺序生成列表的所有排列

时间:2013-04-29 04:48:29

标签: python list while-loop permutation

我非常喜欢初学者。我正在尝试编写一个程序,给定列表中的元素(1-9)的数量作为参数,然后将按字典顺序输出列表的所有排列。在程序中,它将每个排列作为列表添加到一个更大的列表中,该列表按顺序包含所有排列。虽然程序一般没有按预期工作,但我遇到的一个主要问题是这个while循环在第10行,我希望列表在最终排列添加到列表后停止编译。例如,如果我的输入参数是n = 4,则最后一个排列/元素应该是[4,3,2,1]。但是,当我运行此程序时,该元素最后会在列表中三次。我不知道这是怎么回事,一旦它被添加就应该终止while循环。

def ourPermutations(n):
    x=list(range(1,n+1))
    permList = []
    permList+=[x]

    xcopy = x[:]
    finalPerm = xcopy[::-1]


    while x != finalPerm:
        istar = n-2
        while x[istar] > x[istar+1]:
            istar -= 1
        jstar = n-1
        while x[jstar] < x[istar]:
            jstar -= 1
        x[istar],x[jstar] = x[jstar],x[istar]
        if istar+1 == n-1:
            x = x[:]
        else:
            a = x[istar+1:]
            a = a[::-1]
            x = x[:istar+1] + a
        permList += [x]

    return permList

这是我的主要问题;但是,当我运行它时,这个程序仍然缺少元素。它不是很有效,所以如果你看到一个明显错误的地方,请随时告诉我特定的线路是导致我的问题的原因。如果有帮助,这是基于Mathematica 8中使用的相同(和正确)版本:

ourpermutations[n_] := (
    ourlist = {x=Range[1,n]};
    While[
        x != Reverse[Range[1,n]],
        istar = n-1;
        While[x[[istar]] > x[[istar+1, istar--];
        jstar = n; While[x[[jstar]] < x[[istar]], jstar--];
        x[[{istar, jstar}]] = x[[{jstar, istar}]];
        AppendTo[ourlist, x = Join[Take[x,istar], Reverse[Drop[x,istar]]]]
    ];
    ourlist
)

所以这就是我的Python代码应该做的事情;我还是不能这样做。感谢您的任何时间和精力。

1 个答案:

答案 0 :(得分:0)

您似乎遇到了问题,因为您没有尽快复制x因此有时在x添加permList之后修改x = x[:]。这可以通过在while循环开始时添加def ourPermutations(n): x=list(range(1,n+1)) permList = [] permList+=[x] xcopy = x[:] finalPerm = xcopy[::-1] while x != finalPerm: x = x[:] istar = n-2 while x[istar] > x[istar+1]: istar -= 1 jstar = n-1 while x[jstar] < x[istar]: jstar -= 1 x[istar],x[jstar] = x[jstar],x[istar] if istar+1 == n-1: x = x[:] else: a = x[istar+1:] a = a[::-1] x = x[:istar+1] + a permList += [x] return permList >>> ourPermutations(3) [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] >>> ourPermutations(4) [[1, 2, 3, 4], [1, 2, 4, 3], [1, 3, 2, 4], [1, 3, 4, 2], [1, 4, 2, 3], [1, 4, 3, 2], [2, 1, 3, 4], [2, 1, 4, 3], [2, 3, 1, 4], [2, 3, 4, 1], [2, 4, 1, 3], [2, 4, 3, 1], [3, 1, 2, 4], [3, 1, 4, 2], [3, 2, 1, 4], [3, 2, 4, 1], [3, 4, 1, 2], [3, 4, 2, 1], [ 4, 1, 2, 3], [4, 1, 3, 2], [4, 2, 1, 3], [4, 2, 3, 1], [4, 3, 1, 2], [4, 3, 2, 1]] 来解决:

def our_permutations(n):
    x = list(range(1, n+1))
    perm_list = [x]
    final_perm = x[::-1]

    while x != final_perm:
        x = x[:]
        istar = n-2
        while x[istar] > x[istar+1]:
            istar -= 1
        jstar = n-1
        while x[jstar] < x[istar]:
            jstar -= 1
        x[istar],x[jstar] = x[jstar],x[istar]
        if istar+1 != n-1:
            a = x[istar+1:]
            a = a[::-1]
            x = x[:istar+1] + a
        perm_list += [x]

    return perm_list

稍微多一点“pythonic”版本可能看起来像:

itertools.permutation

针对{{1}}检查这些功能表明它们会产生相同的答案,所以看起来你的算法是正确的,除了那个小错误。