问题:对列表中的每对元素进行操作
使用Python,我想比较列表中的每个可能的对。
假设我有
my_list = [1,2,3,4]
我想对列表中2个元素的每个组合进行一个操作(我们称之为foo)。
最终结果应与
foo(1,1)
foo(1,2)
...
foo(4,3)
foo(4,4)
我的第一个想法是手动遍历列表两次,但这似乎并不十分精妙。
回答 0
product()
在itertools
模块中签出。它完全符合您的描述。
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
我有一个类似的问题,在这里找到了解决方案。它的工作无需导入任何模块。
假设一个列表如下:
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')
编辑:进行了简化以简化此解决方案的工作后,我意识到它与Adam Rosenfield是相同的方法。我希望更大的解释能帮助一些人更好地理解它。
回答 2
如果您只是调用一个函数,那么您实际上做不到以下事情:
for i in my_list:
for j in my_list:
foo(i, j)
如果要收集调用函数结果的列表,可以执行以下操作:
[foo(i, j) for i in my_list for j in my_list]
这将为您返回适用foo(i, j)
于每个可能对的结果列表(i, j)
。
回答 3
my_list = [1,2,3,4]
pairs=[[x,y] for x in my_list for y in my_list]
print (pairs)