如何在Python列表中为多个分组生成置换

时间:2018-11-10 13:51:32

标签: python permutation itertools

我知道我们可以使用itertools.permutations排列列表中的不同项目,但是,如果我有一个列表,使得很少有项目需要固定位置,那么很少的项目需要交换一个或几个项目,该怎么办?需要再交换2个?

例如:

test = [1, 6, 2, 12, 5, 13, 11, 14, 15]

如何使用Python itertools.permutation或其他方法来生成具有以下约束的所有可能组合?

更新

1 and 5 have fixed positions
In position 2, I could have either 6 or 11
In position 3, I could have either 2 or 12
In position 4, I could have 2 or 12
In position 6, I could have either 13, 14, 15 and so on

所以,我的列表如下:

[1, (6, 11), (2, 12), (2,12), 5, (13, 14, 15), (6, 11), (13, 14, 15), (13, 14, 15)]

我将数字分组,表示同一组中的数字可以互换。

谢谢。

1 个答案:

答案 0 :(得分:2)

您可以执行以下操作:

from itertools import permutations, product, chain

test = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
groups = [[1], [2, 3, 4], [5], [6, 7], [8, 9], [10], [11, 12, 13], [14], [15, 16]]

result = [list(chain.from_iterable(permutation)) for permutation in product(*map(permutations, groups))]

for e in result[:20]:
    print(e)

输出

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 15]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 12, 14, 15, 16]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 12, 14, 16, 15]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 11, 13, 14, 15, 16]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 11, 13, 14, 16, 15]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 11, 14, 15, 16]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 11, 14, 16, 15]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13, 11, 12, 14, 15, 16]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13, 11, 12, 14, 16, 15]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13, 12, 11, 14, 15, 16]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13, 12, 11, 14, 16, 15]
[1, 2, 3, 4, 5, 6, 7, 9, 8, 10, 11, 12, 13, 14, 15, 16]
[1, 2, 3, 4, 5, 6, 7, 9, 8, 10, 11, 12, 13, 14, 16, 15]
[1, 2, 3, 4, 5, 6, 7, 9, 8, 10, 11, 13, 12, 14, 15, 16]
[1, 2, 3, 4, 5, 6, 7, 9, 8, 10, 11, 13, 12, 14, 16, 15]
[1, 2, 3, 4, 5, 6, 7, 9, 8, 10, 12, 11, 13, 14, 15, 16]
[1, 2, 3, 4, 5, 6, 7, 9, 8, 10, 12, 11, 13, 14, 16, 15]
[1, 2, 3, 4, 5, 6, 7, 9, 8, 10, 12, 13, 11, 14, 15, 16]
[1, 2, 3, 4, 5, 6, 7, 9, 8, 10, 12, 13, 11, 14, 16, 15]

更新

鉴于新的约束,您可以执行以下操作:

from functools import partial
from itertools import combinations, permutations, product, chain

choose_one = partial(lambda r, iterable: combinations(iterable, r), 1)
groups = [[[1]], combinations([6, 11], 1), permutations([2, 12]), [[5]], combinations([13, 14, 15], 1)]

for e in product(*groups, repeat=1):
    print(list(chain.from_iterable(e)))

输出

[1, 6, 2, 12, 5, 13]
[1, 6, 2, 12, 5, 14]
[1, 6, 2, 12, 5, 15]
[1, 6, 12, 2, 5, 13]
[1, 6, 12, 2, 5, 14]
[1, 6, 12, 2, 5, 15]
[1, 11, 2, 12, 5, 13]
[1, 11, 2, 12, 5, 14]
[1, 11, 2, 12, 5, 15]
[1, 11, 12, 2, 5, 13]
[1, 11, 12, 2, 5, 14]
[1, 11, 12, 2, 5, 15]