2009-06-03 61 views
50

使用Python,我想比較列表中的每對可能對。對列表中的每對元素進行操作

假設我有

my_list = [1,2,3,4] 

我想再做一次手術(姑且稱之爲富)從該表中2個元素的每個組合。

最終的結果應該是一樣的

foo(1,1) 
foo(1,2) 
... 
foo(4,3) 
foo(4,4) 

我首先想到的是通過列表中手動迭代兩次,但似乎並不很Python的。

回答

141

檢出itertools模塊中的product()。它完全符合你的描述。

import itertools 

my_list = [1,2,3,4] 
for pair in itertools.product(my_list, repeat=2): 
    foo(*pair) 

這相當於:

my_list = [1,2,3,4] 
for x in my_list: 
    for y in my_list: 
     foo(x, y) 

編輯:有兩個非常相似的功能,以及,permutations()combinations()。爲了說明它們之間的區別:

product()生成元件的每一個可能的配對,包括所有重複:

1,1 1,2 1,3 1,4 
2,1 2,2 2,3 2,4 
3,1 3,2 3,3 3,4 
4,1 4,2 4,3 4,4 

permutations()生成每個唯一一對元件中的所有唯一排序,消除了x,x重複:

. 1,2 1,3 1,4 
2,1 . 2,3 2,4 
3,1 3,2 . 3,4 
4,1 4,2 4,3 . 

最後,combinations()只生成每個唯一的元素對,按字典順序:

. 1,2 1,3 1,4 
. . 2,3 2,4 
. . . 3,4 
. . . . 

所有這三個函數都是在Python 2.6中引入的。

+1

不知道itertools,這是完美的。謝謝 ! – GuiSim 2009-06-03 00:33:34

+1

奇數,當我運行itertools.product(my_list,2)時,它抱怨int不可調用。一旦我將其更改爲:itertools.product(my_list,repeat = 2) – ojrac 2009-06-03 00:34:07

2

如果你只是調用一個函數,你不能真正做到不過如此:

for i in my_list: 
    for j in my_list: 
     foo(i, j) 

如果你想收集調用函數的結果列表,你可以這樣做:

[foo(i, j) for i my_list for j in my_list] 

這將返回給每個可能的對(i, j)應用foo(i, j)的結果列表。

5

我有類似的問題,發現解決方案here。它工作時無需導入任何模塊。

假如像一個列表:

people = ["Lisa","Pam","Phil","John"] 

簡化單行的解決方案是這樣的。

所有可能對,包括重複:

result = [foo(p1, p2) for p1 in people for p2 in people] 

所有可能對,但不包括重複

result = [foo(p1, p2) for p1 in people for p2 in people if p1 != p2] 

唯一對,其中順序無關:

result = [foo(people[p1], people[p2]) for p1 in range(len(people)) for p2 in range(p1+1,len(people))] 

如果你不想操作,但只是爲了獲得配對,刪除功能foo,只使用一個元組就足夠了。

所有可能對,包括重複:

list_of_pairs = [(p1, p2) for p1 in people for p2 in people] 

結果:

('Lisa', 'Lisa') 
('Lisa', 'Pam') 
('Lisa', 'Phil') 
('Lisa', 'John') 
('Pam', 'Lisa') 
('Pam', 'Pam') 
('Pam', 'Phil') 
('Pam', 'John') 
('Phil', 'Lisa') 
('Phil', 'Pam') 
('Phil', 'Phil') 
('Phil', 'John') 
('John', 'Lisa') 
('John', 'Pam') 
('John', 'Phil') 
('John', 'John') 

所有可能對,但不包括重複

list_of_pairs = [(p1, p2) for p1 in people for p2 in people if p1 != p2] 

結果:

('Lisa', 'Pam') 
('Lisa', 'Phil') 
('Lisa', 'John') 
('Pam', 'Lisa') 
('Pam', 'Phil') 
('Pam', 'John') 
('Phil', 'Lisa') 
('Phil', 'Pam') 
('Phil', 'John') 
('John', 'Lisa') 
('John', 'Pam') 
('John', 'Phil') 

唯一對,其中順序無關:

list_of_pairs = [(people[p1], people[p2]) for p1 in range(len(people)) for p2 in range(p1+1,len(people))] 

結果:

('Lisa', 'Pam') 
('Lisa', 'Phil') 
('Lisa', 'John') 
('Pam', 'Phil') 
('Pam', 'John') 
('Phil', 'John') 

編輯:返工來簡化此溶液後,我意識到它是相同的比亞當羅森菲爾德的方法。我希望更大的解釋能幫助一些人更好地理解它。

相關問題