![](/img/trans.png)
[英]Is there a Python function that finds all k-length orderings of a list?
[英]How to get all orderings of a list such that the list is equal to another list?
我有列表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
的特定排列sigma_0
S_B
然后你正在尋找的集合只是{sigma_0 \\circ \\sigma, sigma \\in S_B}
。
現在問題變成:如何確定S_B
? 要做到這一點,您可以觀察到如果您將集合{0,1,2,..,n}
(在您的情況下為n=2
)寫為A_1 \\cup .. A_k
,其中每個A_i
對應於索引在B
中對應於第i個元素(在您的情況下,您將有A_1 = {1,2}
且A_2 = {0}
),那么S_B
每個元素都可以以獨特的方式寫為產品tau_1 \\circ .. tau_k
其中每個tau_i
是一個作用於A_i
的排列。
因此,在您的情況下, S_B = {id, (1,2)}
,您可以使用sigma_0 = (0,2)
。 因此,你所追求的集合是{(0,2), (2,0,1)}
。
這是一種方法。 我的perms
函數生成所有有效的排列。 首先,我收集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)
你可以分三步完成。 首先,從列表B創建一個字典,其中項目為鍵,索引為值。 在您的情況下,列表B的字典:
B = [7, 'x', 'x']
7 - [0]
'x' - [1, 2]
然后,瀏覽列表A並構建一個索引,將List A索引映射到相應的List B索引。 那是:
A = ['x', 'x', 7]
0 - [1, 2]
1 - [1, 2]
2 - [0]
從那里,您可以生成所有有效的映射。 應該很容易編寫代碼,給定上面的索引,將生成[1, 2, 0]
和[2, 1, 0]
。
這是Python中的一些東西。 我使用字符串進行散列,因為我不熟悉如何在Python中將集合和數組作為遞歸參數傳遞,盡管它們可能更有效。
A = ['x', 'x', 7, 'y', 8, 8]
B = [7, 'x', 8, 'x', 8, 'y']
H = {}
# record the indexes of elements in B
for i in xrange(0,len(B)):
if B[i] in H:
H[ B[i] ].append(str(i))
else:
H[ B[i] ] = [str(i)]
# build permutations in the order that the elements are encountered in A
def perms(perm,i,visited,l):
if i==l:
print perm
return
for j in H[ A[i] ]:
if j not in visited:
perms(perm + j,i + 1,visited + j,l)
perms("",0,"",len(A))
輸出:
130524
130542
310524
310542
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.