简体   繁体   English

Python-有遗漏的排列新清单

[英]Python - New list of permutations with omissions

Lets say I have a list of values 可以说我有一个值列表

my_list = [1,2,3,4]

I user itertools.permutations to find all combinations of this list 我使用itertools.permutations查找此列表的所有组合

perms = itertools.permutations(my_list)

Which creates 哪个创造

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

I begin iterating through this and find that I no longer need any items in perms which begin with (4,1... or (3,1... . 我开始对此进行迭代,发现我不再需要以(4,1...(3,1...开头的perms中的任何项目。

How can I recreate this list with those specific omissions? 如何针对那些特定的遗漏重新创建此列表? Iterating through and removing items is not viable as this needs to scale to very large sizes. 遍历和删除项目是不可行的,因为这需要扩展到非常大的尺寸。

EDIT: For clarification (4,1,2,3) should be removed as it starts with (4,1...) , but not (4,2,1,3) as it starts with (4,2...) . 编辑:为澄清(4,1,2,3)应该从(4,1...)开始删除,但不要以(4,2,1,3)(4,2...) (4,2,1,3)开始(4,2,1,3) (4,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)]

Since you state 因为你说

Iterating through and removing items is not viable as this needs to scale to very large sizes. 遍历和删除项目是不可行的,因为这需要扩展到非常大的尺寸。

The best is to wrap the interator produced by permutations that will generate the tuples you want and skip the tuples you do not want: 最好是包装由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)]

Or, use ifilter from itertools : 或者,使用itertools中的ifilter

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

Or, filter directly on Python 3+ since that also creates an iterator vs creating a list as filter on Python 2 does. 或者,直接在Python 3+上进行过滤,因为与在Python 2上进行过滤相比,这还会创建一个迭代器而不是创建一个列表。

You can use a list comprehension to get the expected permutations : 您可以使用列表推导来获得预期的排列:

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

Note that using a set container has O(1) for check the membership.and it would be more efficient if you have more filter numbers! 请注意,使用set容器具有O(1)来检查成员资格。如果您有更多的过滤器编号,它将更加高效!

If you don't want the tuples that starts with 3,1 and 4,1 you can just simply do : 如果您不希望以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)]
>>> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM