对列表中每对元素进行操作

130 投票
5 回答
110374 浏览
提问于 2025-04-15 12:00

我想用Python来比较列表中的每一对元素。

假设我有

my_list = [1,2,3,4]

我想对列表中每两个元素的组合进行一个操作(我们称这个操作为foo)。

最后的结果应该和

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

我最开始的想法是手动遍历列表两次,但这样做似乎不太符合Python的风格。

5 个回答

4

如果你只是调用一个函数,其实没什么比下面这个更简单的了:

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) 上的结果。

22

我之前遇到过类似的问题,找到了解决办法,具体可以参考这里。这个方法不需要导入任何模块。

假设有一个这样的列表:

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的方法是一样的。希望更详细的解释能帮助一些人更好地理解。

294

可以看看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版本中引入的。

撰写回答