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

问题:对列表中的每对元素进行操作

使用Python,我想比较列表中的每个可能的对。

假设我有

my_list = [1,2,3,4]

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

最终结果应与

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

我的第一个想法是手动遍历列表两次,但这似乎并不十分精妙。

Using Python, I’d like to compare every possible pair in a list.

Suppose I have

my_list = [1,2,3,4]

I’d like to do an operation (let’s call it foo) on every combination of 2 elements from the list.

The final result should be the same as

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

My first thought was to iterate twice through the list manually, but that doesn’t seem very pythonic.


回答 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中引入的。

Check out product() in the itertools module. It does exactly what you describe.

import itertools

my_list = [1,2,3,4]
for pair in itertools.product(my_list, repeat=2):
    foo(*pair)

This is equivalent to:

my_list = [1,2,3,4]
for x in my_list:
    for y in my_list:
        foo(x, y)

Edit: There are two very similar functions as well, permutations() and combinations(). To illustrate how they differ:

product() generates every possible pairing of elements, including all duplicates:

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() generates all unique orderings of each unique pair of elements, eliminating the x,x duplicates:

 .   1,2  1,3  1,4
2,1   .   2,3  2,4
3,1  3,2   .   3,4
4,1  4,2  4,3   .

Finally, combinations() only generates each unique pair of elements, in lexicographic order:

 .   1,2  1,3  1,4
 .    .   2,3  2,4
 .    .    .   3,4
 .    .    .    .

All three of these functions were introduced in 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是相同的方法。我希望更大的解释能帮助一些人更好地理解它。

I had a similar problem and found the solution here. It works without having to import any module.

Supposing a list like:

people = ["Lisa","Pam","Phil","John"]

A simplified one-line solution would look like this.

All possible pairs, including duplicates:

result = [foo(p1, p2) for p1 in people for p2 in people]

All possible pairs, excluding duplicates:

result = [foo(p1, p2) for p1 in people for p2 in people if p1 != p2]

Unique pairs, where order is irrelevant:

result = [foo(people[p1], people[p2]) for p1 in range(len(people)) for p2 in range(p1+1,len(people))]

In case you don’t want to operate but just to get the pairs, removing the function foo and using just a tuple would be enough.

All possible pairs, including duplicates:

list_of_pairs = [(p1, p2) for p1 in people for p2 in people]

Result:

('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')

All possible pairs, excluding duplicates:

list_of_pairs = [(p1, p2) for p1 in people for p2 in people if p1 != p2]

Result:

('Lisa', 'Pam')
('Lisa', 'Phil')
('Lisa', 'John')
('Pam', 'Lisa')
('Pam', 'Phil')
('Pam', 'John')
('Phil', 'Lisa')
('Phil', 'Pam')
('Phil', 'John')
('John', 'Lisa')
('John', 'Pam')
('John', 'Phil')

Unique pairs, where order is irrelevant:

list_of_pairs = [(people[p1], people[p2]) for p1 in range(len(people)) for p2 in range(p1+1,len(people))]

Result:

('Lisa', 'Pam')
('Lisa', 'Phil')
('Lisa', 'John')
('Pam', 'Phil')
('Pam', 'John')
('Phil', 'John')

Edit: After the rework to simplify this solution, I realised it is the same approach than Adam Rosenfield. I hope the larger explanation helps some to understand it better.


回答 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)

If you’re just calling a function, you can’t really do much better than:

for i in my_list:
    for j in my_list:
        foo(i, j)

If you want to collect a list of the results of calling the function, you can do:

[foo(i, j) for i in my_list for j in my_list]

which will return you a list of the result of applying foo(i, j) to each possible pair (i, j).


回答 3

my_list = [1,2,3,4]

pairs=[[x,y] for x in my_list for y in my_list]
print (pairs)
my_list = [1,2,3,4]

pairs=[[x,y] for x in my_list for y in my_list]
print (pairs)