Работа над каждой парой элементов в списке
Используя Python, я хотел бы сравнить каждую возможную пару в списке.
Предположим, что
my_list = [1,2,3,4]
Я хотел бы сделать операцию (пусть ее называют foo) для каждой комбинации из 2 элементов из списка.
Конечный результат должен быть таким же, как
foo(1,1)
foo(1,2)
...
foo(4,3)
foo(4,4)
Моя первая мысль состояла в том, чтобы дважды итератировать по списку вручную, но это не кажется очень питоническим.
Ответы
Ответ 1
Отметьте 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.
Ответ 2
У меня была аналогичная проблема и нашел решение здесь. Он работает без необходимости импортировать какой-либо модуль.
Предположим, что список:
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')
Изменить: после передела, чтобы упростить это решение, я понял, что это тот же подход, что и Адам Розенфилд. Надеюсь, что большее объяснение поможет некоторым понять это лучше.
Ответ 3
Если вы просто вызываете функцию, вы не можете сделать намного лучше, чем:
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)
.
Ответ 4
my_list = [1,2,3,4]
pairs=[[x,y] for x in my_list for y in my_list]
print (pairs)