使用Python,我想比較列表中的每對可能對。對列表中的每對元素進行操作
假設我有
my_list = [1,2,3,4]
我想再做一次手術(姑且稱之爲富)從該表中2個元素的每個組合。
最終的結果應該是一樣的
foo(1,1)
foo(1,2)
...
foo(4,3)
foo(4,4)
我首先想到的是通過列表中手動迭代兩次,但似乎並不很Python的。
使用Python,我想比較列表中的每對可能對。對列表中的每對元素進行操作
假設我有
my_list = [1,2,3,4]
我想再做一次手術(姑且稱之爲富)從該表中2個元素的每個組合。
最終的結果應該是一樣的
foo(1,1)
foo(1,2)
...
foo(4,3)
foo(4,4)
我首先想到的是通過列表中手動迭代兩次,但似乎並不很Python的。
檢出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中引入的。
如果你只是調用一個函數,你不能真正做到不過如此:
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)
的結果列表。
我有類似的問題,發現解決方案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')
編輯:返工來簡化此溶液後,我意識到它是相同的比亞當羅森菲爾德的方法。我希望更大的解釋能幫助一些人更好地理解它。
不知道itertools,這是完美的。謝謝 ! – GuiSim 2009-06-03 00:33:34
奇數,當我運行itertools.product(my_list,2)時,它抱怨int不可調用。一旦我將其更改爲:itertools.product(my_list,repeat = 2) – ojrac 2009-06-03 00:34:07