Подтвердить что ты не робот

Как получить все сопоставления между двумя списками?

У нас есть два списка: A и B:

A = ['a','b','c']
B = [1, 2]

Существует ли питонический способ построения множества всех отображений между A и B, содержащих 2 ^ n (здесь 2 ^ 3 = 8)? То есть:

[(a,1), (b,1), (c,1)]
[(a,1), (b,1), (c,2)]
[(a,1), (b,2), (c,1)]
[(a,1), (b,2), (c,2)]
[(a,2), (b,1), (c,1)]
[(a,2), (b,1), (c,2)]
[(a,2), (b,2), (c,1)]
[(a,2), (b,2), (c,2)]

Используя itertools.product, можно получить все кортежи:

import itertools as it
P = it.product(A, B)
[p for p in P]

Что дает:

Out[3]: [('a', 1), ('a', 2), ('b', 1), ('b', 2), ('c', 1), ('c', 2)]
4b9b3361

Ответ 1

Вы можете сделать это с помощью itertools.product и zip

from itertools import product
print [zip(A, item) for item in product(B, repeat=len(A))]

Выход

[[('a', 1), ('b', 1), ('c', 1)],
 [('a', 1), ('b', 1), ('c', 2)],
 [('a', 1), ('b', 2), ('c', 1)],
 [('a', 1), ('b', 2), ('c', 2)],
 [('a', 2), ('b', 1), ('c', 1)],
 [('a', 2), ('b', 1), ('c', 2)],
 [('a', 2), ('b', 2), ('c', 1)],
 [('a', 2), ('b', 2), ('c', 2)]]

product(B, repeat=len(A)) производит

[(1, 1, 1),
 (1, 1, 2),
 (1, 2, 1),
 (1, 2, 2),
 (2, 1, 1),
 (2, 1, 2),
 (2, 2, 1),
 (2, 2, 2)]

Затем мы выберем каждый элемент из продукта и запишем его A, чтобы получить желаемый результат.

Ответ 2

import itertools as it

A = ['a','b','c']
B = [1, 2]

for i in it.product(*([B]*len(A))):
    print(list(zip(A, i)))

выходы:

[('a', 1), ('b', 1), ('c', 1)]
[('a', 1), ('b', 1), ('c', 2)]
[('a', 1), ('b', 2), ('c', 1)]
[('a', 1), ('b', 2), ('c', 2)]
[('a', 2), ('b', 1), ('c', 1)]
[('a', 2), ('b', 1), ('c', 2)]
[('a', 2), ('b', 2), ('c', 1)]
[('a', 2), ('b', 2), ('c', 2)]

Не уверен, что это очень pythonic, это если вы посмотрите на it.product(*([B]*len(A))), потому что он использует несколько особенностей языка, специфичных для python. Но это на самом деле слишком загадочно, чтобы быть pythonic... B повторяется n раз по длине A и распаковывается в функцию продукта.