Python - 有遗漏的新排列列表
Python - New list of permutations with omissions
假设我有一个值列表
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...)
.
开头
您可以使用列表理解来获得预期的排列:
>>> [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
容器检查 membership.and 的时间复杂度为 O(1),如果您有更多过滤器编号,效率会更高!
如果你不想要以 3,1
和 4,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)]
>>>
>>> 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)]
既然你说
Iterating through and removing items is not viable as this needs to
scale to very large sizes.
最好的方法是包装由 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 上过滤那样创建列表。
假设我有一个值列表
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...)
.
您可以使用列表理解来获得预期的排列:
>>> [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
容器检查 membership.and 的时间复杂度为 O(1),如果您有更多过滤器编号,效率会更高!
如果你不想要以 3,1
和 4,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)]
>>>
>>> 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)]
既然你说
Iterating through and removing items is not viable as this needs to scale to very large sizes.
最好的方法是包装由 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 上过滤那样创建列表。