Python新的省略排列列表

2024-04-28 21:32:21 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个值列表

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...)开头的(4,2,1,3)。你知道吗


Tags: 用户编辑列表mylistitertoolsperms项是
3条回答

既然你说

Iterating through and removing items is not viable as this needs to scale to very large sizes.

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

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)))

或者,直接在python3+上进行过滤,因为这也会创建一个迭代器,而不是像python2上的过滤器那样创建一个列表。你知道吗

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

您可以使用列表理解来获得预期的排列:

>>> [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容器检查会员资格。以及如果你有更多的过滤器编号,效率会更高!你知道吗

如果不希望元组以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)]
>>> 

相关问题 更多 >