2011-11-23 4 views
5

Non ho trovato un modo migliore per esprimere questa domanda nel titolo. Se puoi, per favore modifica.come ottenere tutte le possibili combinazioni di elementi dall'elenco bidimensionale in python?

Ho una lista di liste come questa:

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

ora, mi piacerebbe una funzione che sputa fuori tutte le possibili combinazioni in questo modo:

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

in cui né il numero di liste in a è noto in anticipo, né la lunghezza di ciascuno dei sotto-elenchi è conosciuta in anticipo, ma tutte le combinazioni che escono devono contenere 1 elemento da ogni sottolista.

risposta

11

È necessario itertools.product():

>>> list(itertools.product(*a)) 
[('a', 1), ('a', 2), ('b', 1), ('b', 2)] 
+0

Per chi sta chiedendo, il * di fronte a una scompatta l'elenco: http://stackoverflow.com/a/2921893/4549682 – wordsforthewise

0

Questo può essere quello itertools.product() (che Sven cita) fa:

def combs(list1, list2): 
    results = [] 
    for x in list1: 
     for y in list2: 
      l.append([x,y]) 
    return results 
+0

che avrebbe funzionato se ho sempre avuto solo 2 sottoliste, come nell'esempio '[[1,2], ['a', 'b']], e poi passeresti semplicemente le due sotto-liste a questa funzione, ma non è questo il caso, la lista potrebbe anche essere' [[ 'a', 'b', 'c'], [1,2], [{}, [],()]], quindi ora abbiamo 3 sottoliste, quindi quello di cui abbiamo bisogno è una funzione in cui moltiplicare un numero variabile di liste. – bigblind

+0

Ah, ho assunto dal tuo esempio che sarebbe sempre stato coppia. Allora non ho un suggerimento migliore. – Anko

0

Ecco una soluzione che utilizza la ricorsione, combs_r ha accum digerire head (l'elenco successivo in linea) per produrre un più grasso accum0, quindi chiama se stesso ("ricorsione") con tail (gli elenchi rimanenti) e il cum più grasso ora accum0.

Potrebbe essere un utente pesante della memoria poiché ogni chiamata a combs_r aggiunge un nuovo spazio dei nomi, fino alla fine quando tutto si svolge. La persona più conosciuta negli interni di Python potrebbe commentare su questo.

Paga per imparare prolog, IMHO.

def combs(ll): 
    if len(ll) == 0: 
     return [] 
    if len(ll) == 1: 
     return [[item] for item in ll[0]] 
    elif len(ll) == 2: 
     return lmul(ll[0], [[item] for item in ll[1]]) 
    else: 
     return combs_r(ll[1:], ll[0]) 

def combs_r(ll, accum): 
    head = ll[0] 
    tail = ll[1:] 
    accum0 = [] 
    accum0 = lmul(head, accum) 
    if len(tail) == 0: 
     return accum0 
    else: 
     return combs_r(tail, accum0) 

def lmul(head, accum): 
    accum0 = [] 
    for ah in head: 
     for cc in accum: 
      #cc will be reused for each ah, so make a clone to mutate 
      cc0 = [x for x in cc] 
      cc0.append(ah) 
      accum0.append(cc0) 
    return accum0 

sampleip = [['a','b','c'],[1,2], ['A', 'B']] 
sampleip2 = [['a','b','c'],[1,2]] 
sampleip1 = [['a','b','c']] 
sampleip0 = [] 
print combs(sampleip0) 
print combs(sampleip1) 
print combs(sampleip2) 
print combs(sampleip)