二维列表的排列 (Python)
Permutations on 2D lists (Python)
我有一个复杂的排列问题,我发现它很难编码。
请耐心等待,这可能看起来有点难看。
我有这种形式的东西:
L = [ [[(1, 2)], [(1, 2),(1, 3)]], [[(2, 3)]] ]
我想像这样输出所有"permutations":
[ [(1,2),(2,3)], [(2,3),(1,2)], [(1,2),(1,3),(2,3)], [(2,3),(1,2),(1,3)] ]
凭直觉,我需要列表中包含的元组的所有顺序(没有重复)。但是,同一列表中的元组不能在一起。例如。因为 [[(1, 2)], [(1, 2),(1, 3)]], (1,2) 和 (1,2),(1,3) 在同一个列表中。所以输出中的元素不能是 (1,2)(1,3)(1,2).
我编写了一些杂乱的代码来完成这项工作,但需要清理输出:
output=[]
for x in input:
for y in x:
a=[]
for x1 in input:
if x!=x1:
for y1 in x1:
a.append(list(permutations([y,y1],len([y,y1]))))
output.append(a)
这就足够了,但我还需要能够像这样输入:
[[[(1, 2)], [(1, 2), (1, 3)]], [[(2, 3)]], [[(4,5),(6,7)]]
因此,像这样的元素将包含在输出中:
[(4,5),(6,7),(1,2),(2,3)]
有人知道我应该如何处理这个问题吗?或者有什么建议吗?
我可能是错的,但据我了解,你想做几个合奏的笛卡尔积(其元素本身就是合奏):
[[(1, 2)], [(1, 2),(1, 3)]] X [[(2, 3)]]
然后对于这个笛卡尔积的每个元素,对其包含的元素进行所有的排列,在这个例子中,笛卡尔积的元素是:
([(1, 2)],[(2, 3)])
([(1, 2),(1, 3)], [(2, 3)])
最后对每个元素进行所有排列:
第一个元素的排列:([(1, 2)],[(2, 3)]), ([(2, 3)],[(1, 2)])
第二个元素的排列:([(1, 2),(1, 3)], [(2, 3)]), ([(2, 3)],[(1, 2), (1, 3)])
如果这是你想要的,那么你可以使用 itertools
模块中的 product
和 permutations
来完成(你还需要 chain
来正确地转动每个元组列表中的排列并获得您想要的确切输出):
from itertools import product, permutations, chain
L = [ [[(1, 2)], [(1, 2),(1, 3)]], [[(2, 3)]] ]
for element in product(*L):
for permutation in permutations(element):
print(list(chain(*permutation)))
[(1, 2), (2, 3)]
[(2, 3), (1, 2)]
[(1, 2), (1, 3), (2, 3)]
[(2, 3), (1, 2), (1, 3)]
你可以通过列表推导直接得到'permutations'的列表:
result = [list(chain(*permutation)) for element in product(*L) for permutation in permutations(element)]
[[(1, 2), (2, 3)],
[(2, 3), (1, 2)],
[(1, 2), (1, 3), (2, 3)],
[(2, 3), (1, 2), (1, 3)]]
我有一个复杂的排列问题,我发现它很难编码。
请耐心等待,这可能看起来有点难看。
我有这种形式的东西:
L = [ [[(1, 2)], [(1, 2),(1, 3)]], [[(2, 3)]] ]
我想像这样输出所有"permutations":
[ [(1,2),(2,3)], [(2,3),(1,2)], [(1,2),(1,3),(2,3)], [(2,3),(1,2),(1,3)] ]
凭直觉,我需要列表中包含的元组的所有顺序(没有重复)。但是,同一列表中的元组不能在一起。例如。因为 [[(1, 2)], [(1, 2),(1, 3)]], (1,2) 和 (1,2),(1,3) 在同一个列表中。所以输出中的元素不能是 (1,2)(1,3)(1,2).
我编写了一些杂乱的代码来完成这项工作,但需要清理输出:
output=[]
for x in input:
for y in x:
a=[]
for x1 in input:
if x!=x1:
for y1 in x1:
a.append(list(permutations([y,y1],len([y,y1]))))
output.append(a)
这就足够了,但我还需要能够像这样输入:
[[[(1, 2)], [(1, 2), (1, 3)]], [[(2, 3)]], [[(4,5),(6,7)]]
因此,像这样的元素将包含在输出中:
[(4,5),(6,7),(1,2),(2,3)]
有人知道我应该如何处理这个问题吗?或者有什么建议吗?
我可能是错的,但据我了解,你想做几个合奏的笛卡尔积(其元素本身就是合奏):
[[(1, 2)], [(1, 2),(1, 3)]] X [[(2, 3)]]
然后对于这个笛卡尔积的每个元素,对其包含的元素进行所有的排列,在这个例子中,笛卡尔积的元素是:
([(1, 2)],[(2, 3)])
([(1, 2),(1, 3)], [(2, 3)])
最后对每个元素进行所有排列:
第一个元素的排列:([(1, 2)],[(2, 3)]), ([(2, 3)],[(1, 2)])
第二个元素的排列:([(1, 2),(1, 3)], [(2, 3)]), ([(2, 3)],[(1, 2), (1, 3)])
如果这是你想要的,那么你可以使用 itertools
模块中的 product
和 permutations
来完成(你还需要 chain
来正确地转动每个元组列表中的排列并获得您想要的确切输出):
from itertools import product, permutations, chain
L = [ [[(1, 2)], [(1, 2),(1, 3)]], [[(2, 3)]] ]
for element in product(*L):
for permutation in permutations(element):
print(list(chain(*permutation)))
[(1, 2), (2, 3)]
[(2, 3), (1, 2)]
[(1, 2), (1, 3), (2, 3)]
[(2, 3), (1, 2), (1, 3)]
你可以通过列表推导直接得到'permutations'的列表:
result = [list(chain(*permutation)) for element in product(*L) for permutation in permutations(element)]
[[(1, 2), (2, 3)],
[(2, 3), (1, 2)],
[(1, 2), (1, 3), (2, 3)],
[(2, 3), (1, 2), (1, 3)]]