对列表中每对元素进行操作
我想用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版本中引入的。