Python全排列代码

3 投票
6 回答
3859 浏览
提问于 2025-04-16 01:51

我两个月前开始学习编程,在我的一个小项目中,我需要生成一组对象的排列组合。我知道只要搜索一下就能找到方法,但我想自己动手做一个,所以我努力写了自己的排列生成器代码:

def perm(lst, c = [], x = 0):
    i = -1
    g = len(lst) - 1
    if x == g:
        while i < g:
            i += 1
            if lst[i] in c:
                continue
            c.append(lst[i])
            print(c)
            del c[-1]
            i = g
    else:
        while i < g:
            if x == 0:
                del c[:]
            elif g == x:
                del c[-1]
            elif len(c) > x:
                del c[-1]
                continue
            i += 1
            if lst[i] in c:
                continue
            c.append(lst[i])
            x + 1
            perm(lst, c, x + 1)

这是我运行它时得到的结果:

perm(range(2))
[0, 1]
[1, 0]

perm([1, 4, 5])
[1, 4, 5]
[1, 5, 4]
[4, 1, 5]
[4, 5, 1]
[5, 1, 4]
[5, 4, 1]

它的运行效果和我预期的一样,但当我使用更大的列表时,生成所有排列组合需要一些时间。所以我只想要一些关于如何改进我的代码的建议,仅仅是建议。如果你能告诉我该学些什么,才能做出更好的生成器,那就太好了。

提前感谢所有帮助我的人。

6 个回答

3

生成排列通常是通过递归的方式来实现的。假设你有5个物品,你可以通过依次选择这5个物品中的每一个作为答案的第一个元素,然后对剩下的4个物品进行排列,最后把它们组合在一起。

3
>>> from itertools import permutations
>>> list(permutations(range(2)))
[(0, 1), (1, 0)]
>>> list(permutations([1, 4, 5]))
[(1, 4, 5), (1, 5, 4), (4, 1, 5), (4, 5, 1), (5, 1, 4), (5, 4, 1)]

文档中,有适用于旧版本的Python代码。

关于你的代码,有一点要注意,x + 1 这个表达式其实没有任何作用,因为你没有把这个结果赋值给任何东西。

2

要想搞清楚是什么让你的代码变慢,最好的办法就是实际测量一下。光靠猜测什么能让代码跑得快,往往是不准确的。你已经意识到代码运行得慢,是时候进行一些改进了,这个想法是对的。

因为这段代码比较小,timeit模块可能会很有用。你可以把代码分成几个部分,然后分别测量它们的运行时间。一个好的经验法则是,关注内层循环的优化,因为它会被执行很多次。在你的例子中,这个内层循环就是perm函数里面的部分。

另外要注意的是,在Python中,while循环通常比for循环要慢,而列表推导式的速度又比这两者都快。

当你开始写更长的脚本时,你会想要了解如何在Python中进行性能分析,这可以帮助你找出代码慢的地方。希望这些建议能给你一些启发。

撰写回答