我有列表A和B,它们可以重复,例如:
A = ['x', 'x', 7]
B = [7, 'x', 'x']
现在,我希望将列表B置换为列表A的所有索引排列:
[1, 2, 0] # because [B[1], B[2], B[0]] == A
[2, 1, 0] # because [B[2], B[1], B[0]] == A
是否有办法在不迭代所有可能排列的情况下实现这一目标?
我已经用过
import itertools
for p in itertools.permutations(range(len(B))):
if A == permute(B,p):
遍历所有可能的排列并检查我想要的排列,但是我想更快地找到合适的排列.
解决方法:
这是一种方法.我的烫发功能会生成所有有效的排列.首先,我收集B中每个元素的索引,然后以递归方式构建并产生排列,方法是始终为A中的每个项目选择一个仍可用的索引,直到准备产生排列为止.
from collections import defaultdict
def perms(A, B):
indexes = defaultdict(set)
for i, e in enumerate(B):
indexes[e].add(i)
def find(perm):
k = len(perm)
if k == len(A):
yield perm
return
I = indexes[A[k]]
for i in list(I):
I.remove(i)
yield from find(perm + (i,))
I.add(i)
yield from find(())
用法:
A = ['x', 'x', 7]
B = [7, 'x', 'x']
for perm in perms(A, B):
print(perm)
输出:
(1, 2, 0)
(2, 1, 0)