Python全排列代码
我两个月前开始学习编程,在我的一个小项目中,我需要生成一组对象的排列组合。我知道只要搜索一下就能找到方法,但我想自己动手做一个,所以我努力写了自己的排列生成器代码:
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中进行性能分析,这可以帮助你找出代码慢的地方。希望这些建议能给你一些启发。