2017-03-06 9 views
7

Mam dwóch list:Kombinacje dwóch list (nie Element-wise)

a = ['a', 'b'] 
b = [1, 2, 3] 

chcę uzyskać kombinacje wyprodukowanych między elementami listy b i elementów listy A, ale elementy obróbki a jak parami (lub trójek itp.) jak w poniższym przykładzie:

Daje to liczbę kombinacji: len(b) ** len(a).

c = ["a_1 b_1", "a_1 b_2", "a_1 b_3", "a_2 b_1", "a_2 b_2", "a_2 b_3", "a_3 b_1", "a_3 b_2" "a_3 b_3"] 

że próbuje używać itertools.product (jak opisano here), ale daje tylko 6 możliwych kombinacji.

Odpowiedz

14

Możesz użyć itertools.product(..), ale określ repeat na repeat=len(a). Więc można użyć:

from itertools import product 

def mul_product(a,b): 
    for tup in product(b,repeat=len(a)): 
     yield ' '.join('%s_%s'%t for t in zip(a,tup)) 

product(..) wygeneruje krotki jak:

>>> list(product(b,repeat=len(a))) 
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] 

więc tutaj pierwszy element krotki jest ten, który jest dołączony do a_, drugi do b_. Teraz możemy je zip(..) wraz z wykazem a i produkujący

>>> list(map(lambda bi:list(zip(a,bi)),product(b,repeat=len(a)))) 
[[('a', 1), ('b', 1)], [('a', 1), ('b', 2)], [('a', 1), ('b', 3)], [('a', 2), ('b', 1)], [('a', 2), ('b', 2)], [('a', 2), ('b', 3)], [('a', 3), ('b', 1)], [('a', 3), ('b', 2)], [('a', 3), ('b', 3)]] 

teraz to tylko kwestia formatowania ('%s_%s'%t) i ' '.join(..) ining nimi razem i yield je (lub użyć listowych produkować listę).

Wynik na wprowadzenie próbki wynosi:

>>> list(mul_product(a,b)) 
['a_1 b_1', 'a_1 b_2', 'a_1 b_3', 'a_2 b_1', 'a_2 b_2', 'a_2 b_3', 'a_3 b_1', 'a_3 b_2', 'a_3 b_3'] 

Zauważ, że tutaj elementy są generowane leniwie. Może to być użyteczne, jeśli na przykład interesujesz się tylko pierwszymi k lub gdy nie chcesz generować wszystkich naraz.

4

Można jawnie tworzyć parami elementów za pomocą itertools.product, a następnie działać na tych parach dzięki itertools.product

import itertools 
a = ['a', 'b'] 
b = [1, 2, 3] 
pairs = [list(itertools.product([ai], b)) for ai in a] 

pairs będzie zawierać dwie listy, które wprowadzane do itertools.product ponownie.

list(itertools.product(*pairs)) 

Wynikiem jest:

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