Operation on every pair of element in a list

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.


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.

Tags:

Python