在Python中递归实现排列

时间:2013-05-15 22:45:44

标签: python string permutation

我很抱歉已经有很多关于这个问题的帖子了。但是,我很难在自己的实现中看到我出错的地方。所以我正在尝试编写一个函数,它接受一个字符串并以列表的形式返回所有可能的排列。

理论上它应该是这样的:

allPermutations(“abc ... z”)= [a + allPermutations(b,c,... z),b + allPermutations(a,c ... z)...]

我当前的实现,当在字符串上测试时,“Hello”,输出一堆重复的排列。任何人都可以帮我看看我哪里错了。感谢您的协助!

以下是代码:

def allPermutations(strng):
    if len(strng) ==1:
        return [strng]
    perm_list = []
    for i in strng:
        smallerStr = strng.replace(i,"",1)
        z = allPermutations(smallerStr)

        for t in z:
            perm_list.append(i+t)        
    return perm_list

2 个答案:

答案 0 :(得分:2)

请仔细查看itertools模块。就是这样:

import itertools
[ ''.join(i) for i in itertools.permutations(mystring) ]

一个例子:

[ ''.join(i) for i in itertools.permutations('abc')]
#['abc', 'acb', 'bac', 'bca', 'cab', 'cba']

答案 1 :(得分:2)

如果你有重复的字母,你将会有重复的排列,因为这就是你的逻辑所做的。

例如,使用'Hello',对于第一个l,您为'l' + perm的每个排列添加'Helo',然后为第二个l添加'l' + perm },你再次'Helo'的每个排列添加set(strng)

有几种方法可以显示没有重复的排列。最简单的方法是循环strng而不是def allPermutations(strng): if len(strng) ==1: return [strng] perm_list = [] for i in set(strng): smallerStr = strng.replace(i,"",1) z = allPermutations(smallerStr) for t in z: perm_list.append(i+t) return perm_list

for i in strng:
    smallerStr = strng.replace(i,"",1)

作为旁注,你几乎不想做这样的事情:

for x in lst:
    idx = lst.find(x)

......或

'l'

除了对你已经拥有的东西进行不必要搜索的明显性能问题之外,如果你有任何重复的元素,它就没有办法正确。例如,无论您是尝试替换/查找/ {/ 1}}中的第一个'Hello'还是第二个,它都会替换第一个。

执行此操作的正确方法是使用enumerate。例如:

for idx, i in enumerate(strng):
    smallerStr = strng[:idx] + strng[idx+1:]

在这种特殊情况下,它无关紧要,因为您实际上并不关心是删除第一个l还是第二个{{1}}。但是你应该只依靠它,如果你已经考虑过并确保它是正确的 - 并且可能添加一个注释来解释为什么它是正确的。一般来说,就是不要这样做。