Python - 带有遗漏的排列的新列表

时间:2015-05-22 16:04:58

标签: python permutation

假设我有一个值列表

my_list = [1,2,3,4]

我使用itertools.permutations来查找此列表的所有组合

perms = itertools.permutations(my_list)

创建

[(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)]

我开始对此进行迭代,发现我不再需要perms中以(4,1...(3,1...开头的任何项目。

如何使用这些特定的遗漏重新创建此列表?迭代和删除项目是不可行的,因为这需要扩展到非常大的尺寸。

编辑:澄清(4,1,2,3)应该从(4,1...)开始删除,而不是(4,2,1,3),因为它始于(4,2...)

3 个答案:

答案 0 :(得分:2)

>>> from itertools import permutations
>>> my_list = [1,2,3,4]
>>> perms = permutations(my_list)
>>> perms
<itertools.permutations object at 0x107a63ad0>
>>> perms = filter(lambda x: x[:2] != (4,1) and x[:2] != (3,1), perms)
>>> perms
[(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, 2, 1, 4), (3, 2, 4, 1), (3, 4, 1, 2), (3, 4, 2, 1), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]

答案 1 :(得分:1)

既然你陈述了

  

迭代和删除项目是不可行的,因为这需要   扩展到非常大的尺寸。

最好是包装由permutations生成的生成器,它将生成你想要的元组并跳过你不想要的元组:

my_list = [1,2,3,4]

def my_perms(my_list, f):
    for e in permutations(my_list):
        if f(e):
            yield e 

>>> list(my_perms(my_list, lambda t: t[:2] not in {(4,1), (3,1)}))
[(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, 2, 1, 4), (3, 2, 4, 1), (3, 4, 1, 2), (3, 4, 2, 1), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]

或者,使用ifilter from itertools

>>> list(ifilter(lambda t: t[:2] not in {(4,1), (3,1)}, permutations(my_list)))

或者,直接在Python 3+上过滤,因为这也创建了一个迭代器,而不是像Python 2那样创建一个列表作为过滤器。

答案 2 :(得分:0)

您可以使用列表推导来获得预期的排列:

>>> [i for i in perms if i[0] not in {3,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)]

请注意,使用set容器有O(1)来检查成员资格。如果您有更多的过滤器编号,它会更有效!

如果您不想要以3,14,1开头的元组,您只需执行以下操作:

>>> perms = it.permutations(my_list)
>>> [i for i in perms if i[:2] !=[4,1] and i[:2] !=[4,1]]
[(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)]
>>>