2015-12-04 61 views
1

數字排列功能,創建所有可能排列的列表。 在此代碼上工作了一段時間,它運行良好,我試圖找到一個更短,更有效的寫作方式。從數字變量或數字列表中排序的數字排列列表,無重複

a = [3,7,9] 
perms = lambda a:list(sorted(z) for z in map(lambda p:dict.fromkeys([str(sum(v* (10**(len(p) -1 - i)) for i,v in enumerate(item))).zfill(len(a)) for item in itertools.permutations(p)]).keys(), [[int(x) for x in ''.join(str(i) for i in a)]]))[0] 

代碼返回:

['379', '397', '739', '793', '937', '973'] 

你也可以輸入數字字符串變量

a = '468' 
perms(a) 
['468', '486', '648', '684', '846', '864'] 

這是代碼,而不是返回元組或列表不同。它以字符串格式返回結果列表。此外,您可以輸入數字字符串,元組或列表。相信我在發佈之前檢查過任何重複內容。

三位數工作得很好

perms('000') 
['000'] 

其他代碼生成此

['000', '000', '000', '000', '000', '000'] 

此外,該代碼返回的有序列表。

+1

[如何在Python中生成列表的所有排列]可能的重複(http://stackoverflow.com/questions/104420/how-to-generate-all-permutations-of-a-list-in-python ) – Tempux

+2

如果您可以使用模塊,那麼:https://docs.python.org/2/library/itertools.html?highlight=itertools#itertools.permutations –

+0

我發現這篇文章對學習如何生成排列非常有幫助。 http://sahandsaba.com/combinatorial-generation-using-coroutines-in-python.html –

回答

1

您已經使用itertools.permutations,爲什麼不乾脆:

def perms(iterable): 
    return [''.join(p) for p in (map(str, perm) for perm in itertools.permutations(iterable))] 

>>> perms('123') 
# Result: ['123', '132', '213', '231', '312', '321'] 

更新:如果你想避免重複,可以通過使用一組,延長像這樣的功能在Why does Python's itertools.permutations contain duplicates? (When the original list has duplicates)

闡述
def unique_perms(iterable): 
    perm_set = set() 
    permutations = [i for i in itertools.permutations(iterable) if i not in perm_set and not perm_set.add(i)] 
    return [''.join(p) for p in (map(str, perm) for perm in permutations)] 

這仍然比海報原始方法快得多,特別是對於'000'等例子並且是穩定的(保留排列順序)。

+0

好的,有什麼問題?似乎符合您的規範和示例用例 – lemonhead

+0

代碼適合我。速度提高了一倍以上。 x 100000:2.33799177202 perms x 100000:0.75015824786 –

+0

@Marcel Wilson,非常感謝您的檢查。我想OP可能會在評論中表示他們不想重複,但我會等更新我的答案後再聽到確認。 – lemonhead