2015-05-18 21 views
5

Prima di tutto volevo dire che il mio titolo probabilmente non descrive correttamente la mia domanda. Non so come si chiama il processo che sto cercando di realizzare, il che ha reso molto difficile la ricerca di una soluzione su StackOverflow o Google. Un suggerimento su questo potrebbe già aiutarmi molto!Python: combinazione in elenchi di elenchi (?)

Quello che attualmente ho sono fondamentalmente due liste con liste come elementi. Esempio:

List1 = [ [a,b], [c,d,e], [f] ] 
List2 = [ [g,h,i], [j], [k,l] ] 

Queste liste sono fondamentalmente vertici di un grafo che sto cercando di creare più avanti nel mio progetto, in cui i bordi dovrebbero essere da List1 a List2 per righe.

Se guardiamo la prima riga di ciascuna delle liste, Ho quindi:

[a,b] -> [g,h,i] 

Tuttavia, voglio avere assingments/bordi degli elementi unici, quindi ho bisogno:

[a] -> [g] 
[a] -> [h] 
[a] -> [i] 
[b] -> [g] 
[b] -> [h] 
[b] -> [i] 

il risultato che voglio avere è un altro elenco, con queste assigments unici come elementi, vale a dire

List3 = [ [a,g], [a,h], [a,i], [b,g], ...] 

C'è un modo elegante per ottenere da Lista1 e Lista2 a Lista 3?

Il modo in cui volevo ottenere è quello di andare riga per riga, determinare la quantità di elementi di ogni riga e quindi scrivere clausole e cicli per creare un nuovo elenco con tutte le combinazioni possibili. Questo, tuttavia, sembra un modo molto inefficiente per farlo.

+0

Sembra che si desidera che i 'itertools. prodotto di ciascuna coppia fatto da 'zip'ping (o' itertools.izip'ping in 2.x) le due liste insieme. – jonrsharpe

+0

@jonrsharpe mi ha battuto, ma sono d'accordo, questo è un lavoro per itertools (https://docs.python.org/2/library/itertools.html) – firelynx

+0

Grazie per i vostri commenti, penso che questo sia esattamente ciò che Stavo cercando! Sto provando la soluzione descritta da Cyber ​​qui sotto. – user4911943

risposta

13

È possibile zip i due elenchi, quindi utilizzare itertools.product per creare ciascuna delle combinazioni. È possibile utilizzare itertools.chain.from_iterable per appiattire l'elenco risultante.

>>> import itertools 
>>> List1 = [ ['a','b'], ['c','d','e'], ['f'] ] 
>>> List2 = [ ['g','h','i'], ['j'], ['k','l'] ] 
>>> list(itertools.chain.from_iterable(itertools.product(a,b) for a,b in zip(List1, List2))) 
[('a', 'g'), ('a', 'h'), ('a', 'i'), ('b', 'g'), ('b', 'h'), ('b', 'i'), ('c', 'j'), ('d', 'j'), ('e', 'j'), ('f', 'k'), ('f', 'l')] 
+0

dal momento che si utilizza itertools, si può anche la catena –

+1

oh sì :) buona cattura – CoryKramer

+1

'chain.from_iterable' potrebbe essere utilizzato per appiattire la lista. Ovviamente potrebbe essere necessaria una chiamata 'list()' in più se un generatore non è sufficiente. – Matthias

0
import itertools 
k = [] 
for a,b in zip(List1,List2): 
    for j in itertools.product(a,b): 
     k.append(j) 
print k 
+0

Qualcosa di simile alla soluzione di cui sopra senza usare itertools.chain() – rajeshv90

2

Se non si desidera utilizzare itertools, è anche possibile utilizzare list comprehensions in combinazione con zip per fare questo piuttosto elegante:

lst1 = [['a','b'], ['c','d','e'], ['f']] 
lst2 = [['g','h','i'], ['j'], ['k','l']] 
edges = [[x, y] for il1, il2 in zip(lst1, lst2) for x in il1 for y in il2]