2014-10-06 67 views
0

我需要從另一個預定義列表構造所有可能排列的列表。我希望能夠使用列表解析,但我願意接受其他建議。帶有可變長度輸出的列表理解

我遇到的問題是列表元素的輸出可能是任何用戶定義的正整數長度,我還沒有碰到任何指向我如何自動化的方向(如果有可能的)。

bases = ['A', 'C', 'G', 'T'] 

所以,如果我想爲3的輸出,我需要

[x+y+z for x in bases for y in bases for z in bases] 

和4個輸出,我需要

[w+x+y+z for w in bases for x in bases for y in bases for z in bases] 
+0

「排列」是指輸入的重新排列(無重複元素)。根據你的例子,這不是你想要的。 – interjay 2014-10-06 00:22:26

+0

如果你真的想看看它是什麼樣子的'列表理解',這將工作:'產品= lambda項目,l:[i + j爲我在產品中的j項目(項目,l-1)]如果l-1其他項目' – Jollywatt 2014-10-06 23:36:34

回答

6
import itertools 
print(list(itertools.permutations(bases))) 
# => [('A', 'C', 'G', 'T'), ('A', 'C', 'T', 'G'), ('A', 'G', 'C', 'T'), ('A', 'G', 'T', 'C'), ('A', 'T', 'C', 'G'), ('A', 'T', 'G', 'C'), ('C', 'A', 'G', 'T'), ('C', 'A', 'T', 'G'), ('C', 'G', 'A', 'T'), ('C', 'G', 'T', 'A'), ('C', 'T', 'A', 'G'), ('C', 'T', 'G', 'A'), ('G', 'A', 'C', 'T'), ('G', 'A', 'T', 'C'), ('G', 'C', 'A', 'T'), ('G', 'C', 'T', 'A'), ('G', 'T', 'A', 'C'), ('G', 'T', 'C', 'A'), ('T', 'A', 'C', 'G'), ('T', 'A', 'G', 'C'), ('T', 'C', 'A', 'G'), ('T', 'C', 'G', 'A'), ('T', 'G', 'A', 'C'), ('T', 'G', 'C', 'A')] 

理解是壞的工具(至少由他們自己),因爲你需要遞歸(或者至少遞歸到什麼遞歸)來正確地處理變長度的li ST。

編輯:現在,你的文字說「排列」,這是當元素不重複,只是洗牌。你的代碼表明你可能在考慮笛卡爾產品,每個位置都是從集合中獨立選擇的;在這種情況下,你要itertools.product

import itertools 
print(list(itertools.product(bases, repeat=3))) 
# => [('A', 'A', 'A'), ('A', 'A', 'C'), ('A', 'A', 'G'), ('A', 'A', 'T'), ('A', 'C', 'A'), ('A', 'C', 'C'), ('A', 'C', 'G'), ('A', 'C', 'T'), ('A', 'G', 'A'), ('A', 'G', 'C'), ('A', 'G', 'G'), ('A', 'G', 'T'), ('A', 'T', 'A'), ('A', 'T', 'C'), ('A', 'T', 'G'), ('A', 'T', 'T'), ('C', 'A', 'A'), ('C', 'A', 'C'), ('C', 'A', 'G'), ('C', 'A', 'T'), ('C', 'C', 'A'), ('C', 'C', 'C'), ('C', 'C', 'G'), ('C', 'C', 'T'), ('C', 'G', 'A'), ('C', 'G', 'C'), ('C', 'G', 'G'), ('C', 'G', 'T'), ('C', 'T', 'A'), ('C', 'T', 'C'), ('C', 'T', 'G'), ('C', 'T', 'T'), ('G', 'A', 'A'), ('G', 'A', 'C'), ('G', 'A', 'G'), ('G', 'A', 'T'), ('G', 'C', 'A'), ('G', 'C', 'C'), ('G', 'C', 'G'), ('G', 'C', 'T'), ('G', 'G', 'A'), ('G', 'G', 'C'), ('G', 'G', 'G'), ('G', 'G', 'T'), ('G', 'T', 'A'), ('G', 'T', 'C'), ('G', 'T', 'G'), ('G', 'T', 'T'), ('T', 'A', 'A'), ('T', 'A', 'C'), ('T', 'A', 'G'), ('T', 'A', 'T'), ('T', 'C', 'A'), ('T', 'C', 'C'), ('T', 'C', 'G'), ('T', 'C', 'T'), ('T', 'G', 'A'), ('T', 'G', 'C'), ('T', 'G', 'G'), ('T', 'G', 'T'), ('T', 'T', 'A'), ('T', 'T', 'C'), ('T', 'T', 'G'), ('T', 'T', 'T')] 
+0

給出的例子,OP想要的實際上是產品而不是排列。 – interjay 2014-10-06 00:20:52

+0

@interjay:好點。但是,不確定我是否相信代碼,所以讓我們給出兩個選項。 – Amadan 2014-10-06 00:22:46

0

這裏是如何做到這一點不itertools。它只是一個返回字符串列表的遞歸函數。

def product(items, length): 
    if length == 1: 
     return items 

    combos = [] 
    for i in items: 
     for j in product(items, length-1): 
      combos.append(i+j) 

    return combos 

print(product('ACGT', 3)) 

#>>> ['AAA', 'AAC', 'AAG', 'AAT', 'ACA', 'ACC', 'ACG', 'ACT' ...