操作列表中的每一对元素
使用Python,我想比较列表中的每个可能的对。
假设我有
my_list = [1,2,3,4]
我想在列表中的2个元素的每个组合上做一个操作(让我们称之为foo)。
最后的结果应该是一样的
foo(1,1) foo(1,2) ... foo(4,3) foo(4,4)
我的第一个想法是手动遍历列表两次,但似乎并不pythonic。
在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)
编辑:有两个非常相似的function, 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()
生成每个唯一元素对的所有唯一sorting,消除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中引入的。
我有一个类似的问题,并find了解决办法。 它不需要导入任何模块。
假设列表如下:
people = ["Lisa","Pam","Phil","John"]
简化的单线解决scheme看起来像这样。
所有可能的配对 ,包括重复:
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')
编辑:在返工之后,为了简化这个解决scheme,我意识到这是和Adam Rosenfield相同的方法。 我希望更大的解释能帮助一些人更好地理解它。
如果你只是调用一个函数,你不可能比以下更好:
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)
的结果列表。