不重复python的排列

时间:2013-11-26 17:53:37

标签: python list python-2.7 permutation

Python中是否有一种方法可以生成列表的所有排列而不会获得同一列表的两个副本(由于列表中的相同元素)。

例如,列表[“up”,“up”]应该只生成列表[“up”,“up”]而不是两次。

另一个例子是[“up”,“up”,“right”]只返回:

["up", "up", "right"]
["up", "right", "up"]
["right", "up", "up"]

而不是以下内容:

["up", "up", "right"]
["up", "right", "up"]
["right", "up", "up"]
["up", "up", "right"]
["up", "right", "up"]
["right", "up", "up"]

例如,此脚本未提供所需的列表。

>>> import itertools
>>> a = list(itertools.permutations(["up","up","down"]))
>>> print a
[('up', 'up', 'down'), ('up', 'down', 'up'), ('up', 'up', 'down'), ('up', 'down', 'up'), ('down', 'up', 'up'), ('down', 'up', 'up')]

注意:如何使用大小为20或更大的较大列表来加快速度?

3 个答案:

答案 0 :(得分:4)

你可以做到

print list(set(a))

样本:

>>> import itertools
>>> a = list(itertools.permutations(["up","up","down"]))
>>> a
[('up', 'up', 'down'), ('up', 'down', 'up'), ('up', 'up', 'down'), ('up', 'down', 'up'), ('down', 'up', 'up'), ('down', 'up', 'up')]
>>> set(a)
set([('up', 'up', 'down'), ('down', 'up', 'up'), ('up', 'down', 'up')])
>>> list(set(a))
[('up', 'up', 'down'), ('down', 'up', 'up'), ('up', 'down', 'up')]
>>> 

答案 1 :(得分:3)

您可以获得set结果:

>>> set(itertools.permutations(a))
set([('up', 'up', 'right'), ('right', 'up', 'up'), ('up', 'right', 'up')])

这可确保您不会在输出中获得重复项。

您当然可以将一组转换回list()列表。

答案 2 :(得分:2)

这不是一个Python问题,这是一个数学问题。 (在评论中发现OP不在列表本身之后,而只是在计数之后。)

如果你有30个插槽要填充15“向上”和15“向下”,那么你需要从30个可能中选择15个不同的位置放置“向上”,然后其余的被强制要“失败”。

在30中选择15个不同的数字是30选择15,或30!/((15!)*((30-15)!)):

>>> from math import factorial
>>> factorial(30)/factorial(15)/factorial(30-15)
155117520L

我们可以手动检查此表达式以获取较小的列表:

>>> from itertools import permutations
>>> len(set(permutations(["up"]*7+["down"]*3)))
120
>>> factorial(10)/factorial(7)/factorial(10-7)
120