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)
fonte
2011-11-24 01:38:50
Per chi sta chiedendo, il * di fronte a una scompatta l'elenco: http://stackoverflow.com/a/2921893/4549682 – wordsforthewise