2011-02-24 25 views
7

假設我有這樣的事情:獲取列表中的每一個可能的組合

L1=['cat', 'dog', 'fish', 'rabbit', 'horse', 'bird', 'frog', 'mouse'...] 

for x in L1: 
    input1= open('file_%s'%(x), 'r') 
    file1= pickle.load(input1) 
    for x in L1: 
     input2= open('file_%s'%(x), 'r') 
     file2= pickle.load(input2) 

,我想獲得的文件的每個組合無需重複那些已經完成的組合(一旦cat_dog做不做dog_cat再次)。有沒有辦法做到這一點?如果這有什麼不同,我真正的名單是按字母順序排列的。

+4

這已經被問很多次所以可能會關閉。導入itertools; itertools.combinations(['貓','狗','魚'],2) – DisplacedAussie 2011-02-24 14:59:39

+0

可能重複[Python代碼從列表中挑選出所有可能的組合?](http:// stackoverflow。com/questions/464864/python-code-to-pick-out-all-possible-combinations-from-a-list) – tzot 2011-03-19 10:21:46

回答

5

你也可以做一個發電機:

L1=['cat', 'dog', 'fish', 'rabbit', 'horse', 'bird', 'frog', 'mouse'] 
tuples = [(x,y) for x in L1 for y in L1 if x != y] 
for entry in tuples: 
    if (entry[1], entry[0]) in tuples: 
     tuples.remove((entry[1],entry[0])) 
for pair in tuples: 
    input1= open('file_%s'%(pair[0]), 'r') 
    file1= pickle.load(input1) 
    input2= open('file_%s'%(pair[1]), 'r') 
    file2= pickle.load(input2) 

之後第一環路中,tuples內容是:

('cat', 'dog') 
('cat', 'fish') 
('cat', 'rabbit') 
('cat', 'horse') 
('cat', 'bird') 
('cat', 'frog') 
('cat', 'mouse') 
('dog', 'fish') 
('dog', 'rabbit') 
('dog', 'horse') 
('dog', 'bird') 
('dog', 'frog') 
('dog', 'mouse') 
('fish', 'rabbit') 
('fish', 'horse') 
('fish', 'bird') 
('fish', 'frog') 
('fish', 'mouse') 
('rabbit', 'horse') 
('rabbit', 'bird') 
('rabbit', 'frog') 
('rabbit', 'mouse') 
('horse', 'bird') 
('horse', 'frog') 
('horse', 'mouse') 
('bird', 'frog') 
('bird', 'mouse') 
('frog', 'mouse') 
+0

這是完美的,正是我需要的感謝@Nate! – marsx 2011-02-24 15:41:37

+2

這不是一個好辦法。看看itertools解決方案! Itertools避免了首先生成完整列表 - 在這個實現中,元組列表長度爲n^2個項目。 itertools解決方案不需要存儲列表。 – 2012-05-10 13:45:23

2

itertools可以執行組合和排列(你想要前者)。據我所知,你不能真正指定輸出格式,所以你會得到「catdog」作爲輸出,但文檔頁面讓你瞭解組合函數的工作原理,所以你可以調整它來構建你需要什麼。

4

itertools.combinations怎麼樣?

用例:

>>> list(itertools.combinations([1, 2, 3, 4, 5, 6], 2)) 
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (2, 5), (2, 6), (3, 4), 
(3, 5), (3, 6), (4, 5), (4, 6), (5, 6)] 

第一個參數是一個可迭代,第二是r,子序列的長度返回。

然後,您可以使用地圖或理解串聯輕鬆的結果:

map(lambda x: x[0] + "_" + x[1], itertools.combinations(["cat", "dog", "fish"], 2))) 

x在lambda是一個尺度的r元組。的

結果上面會:

['cat_dog', 'cat_fish', 'dog_fish'] 
22

在現實中你會問如何做的是生產的名稱列表(相對於所有採取項的所有組合它們的可能組合)。

這意味着你可以使用內置的itertools.combinations()發生器功能可輕鬆地(高效地)產生對名字的你想不重複:

L1 = ['cat', 'dog', 'fish', 'rabbit', 'horse', 'bird', 'frog', 'mouse'] 

for pair in combinations(L1, 2): 
    print(pair) 
    input1 = open('file_%s' % pair[0], 'r') 
    input2 = open('file_%s' % pair[1], 'r') 

雙處理:

('cat', 'dog') 
('cat', 'fish') 
('cat', 'rabbit') 
('cat', 'horse') 
('cat', 'bird') 
('cat', 'frog') 
('cat', 'mouse') 
('dog', 'fish') 
('dog', 'rabbit') 
('dog', 'horse') 
('dog', 'bird') 
('dog', 'frog') 
('dog', 'mouse') 
('fish', 'rabbit') 
('fish', 'horse') 
('fish', 'bird') 
('fish', 'frog') 
('fish', 'mouse') 
('rabbit', 'horse') 
('rabbit', 'bird') 
('rabbit', 'frog') 
('rabbit', 'mouse') 
('horse', 'bird') 
('horse', 'frog') 
('horse', 'mouse') 
('bird', 'frog') 
('bird', 'mouse') 
('frog', 'mouse') 
3
import itertools 
import cPickle 

def unique_pairs(lst): 
    return itertools.combinations(lst, 2) 

FNAME = "file_{0}".format 
def load_pickle(fname): 
    with open(fname) as inf: 
     return cPickle.load(inf) 

def naive_method(lst): 
    # load each file every time it is requested 
    for x,y in unique_pairs(lst): 
     input1 = load_pickle(FNAME(x)) 
     input2 = load_pickle(FNAME(y)) 
     # do something with input1 and input2 

def better_method(lst): 
    # if you have enough memory for it! 
    dat = [load_pickle(FNAME(i)) for i in lst] 
    for x,y in unique_pairs(range(len(lst))): 
     input1 = dat[x] 
     input2 = dat[y] 
     # do something with input1 and input2 
0

爲組合創建的替代,沒有模塊導入。類似@ Nate的答案,但稍微不太複雜,創建具有單品副本,並減少對飛(而不是生成對列表和列表搜索減少):

L1 = ['cat', 'dog', 'fish', 'rabbit', 'horse', 'bird', 'frog', 'mouse'] 
Laux = L1[:] 

pairs = [] 
for a in L1: 
    Laux.remove(a) 
    for b in Laux: 
     pairs += [(a,b)] 
相關問題