2012-05-02 17 views
8

Questo è il modulo di esempio, proverò a spiegarlo in parole successive. Ho una lista da rompere una stringa ...Come elaborare una stringa in un livello di sottoliste

dicono

[a, a, a, b, a, a, b, a, c, a, b, a, a, c, a, c, a] 

dove b è criteri 1 e C è criteri 2

voglio rompere in una lista come questa:

[a, a, a, [b, a, a, [b, a, c], a, [b, a, a, c], a, c], a] 

Quindi voglio per elaborare la stringa in modo tale che quando vado attraverso di essa, se la voce corrisponde ai criteri 1, aprire un nuovo elenco, se l'articolo corrisponde ai criteri 2, chiudere l'elenco di un torna indietro di un livello sopra.

Ho provato a fare qualcosa di simile, ma non sta funzionando molto bene.

def sublist(self, l): 
    for line in list: 
    if not b: 
    self.data.append(line) 
    else: 
    sublist(l[line:])  #<----- not sure how to recurse it. 

ho visto lista rottura nella lista di dimensioni uguali davanti su StackOverflow, ma non una rottura in elenco secondario utilizzando una serie di criteri.

Sono abbastanza nuovo in Python, quindi non ho molta familiarità con le strutture dati e gli strumenti di iterazione.

risposta

10

qui si va:

lst = "aaabaabacabaacaca" 

def go(it): 
    for x in it: 
     if x == 'b': 
      yield [x] + list(go(it)) 
     else: 
      yield x 
      if x == 'c': 
       break 


print list(go(iter(lst))) 
+2

Nice. I generatori semplificano decisamente la struttura ricorsiva. – Marcin

+0

(+1) Bella soluzione! – NPE

+0

Si noti che questo gestisce un "underflow" terminando l'output. Questo potrebbe non essere ciò che è voluto. – Marcin

1
addlist = [] 
alllists = [] 
for item in mylist: 
    if item == b: 
     newlist = [item] 
     addlist.append(newlist) 
     alllists.append(addlist) 
     addlist = newlist 
    elif item == c: 
     addlist.append(item) 
     addlist = alllists.pop() 
    else: 
     addlist.append(item) 

È possibile che questo funzionerà finché le vostre b e c delimitatori sono in equilibrio; in particolare, se hai un eccesso di c s, avrai un underflow dello stack.

Mentre di solito mi piacciono le soluzioni ricorsive, questo ha il vantaggio di rendere esplicito lo stack, che in questo caso, a mio parere, porta ad un codice più semplice.

0

Quanto segue farà:

a, b, c = 1, 2, 3 

def sublist(l): 
    ret = [] 
    while l: 
    val = l.pop(0) 
    if val == b: 
     ret.append([val] + sublist(l)) 
    else: 
     ret.append(val) 
     if val == c: break 
    return ret 

l = [a, a, a, b, a, a, b, a, c, a, b, a, a, c, a, c, a] 
print l 
print sublist(l) 

noti che questo ha l'effetto collaterale di modificare l. È banale cambiarlo facendo una copia.

1

con una pila:

def parseList(inList): 
    stack = [[]] 
    for element in inList: 
     if element == 'b': 
      stack.append([element]) 
      stack[-2].append(stack[-1]) 
     elif element == 'c': 
      stack.pop().append(element) 
     else: 
      stack[-1].append(element) 
    return stack[0] 

questo si romperà se ci sono più 'c di rispetto' di

+0

Questa soluzione non funziona, con l'esempio nella domanda di OP produce un 'IndexError: elenco indice fuori intervallo' –

+0

grazie Oscar, non l'ho provato prima di postare. fisso. – sobel

0

In stile ricorsione vero e proprio che si possa fare la b seguente:

x = yourlist 
i = 0 
def lets_parse(): 
    global i 
    fnlist = [] 
    while i < len(x) 
     if x[i] == 'c': 
      fnlist.append(x[i]) 
      i += 1 
     return fnlist 
     elif x[i] == 'b': 
      i += 1 
      f = lets_parse() 
      f.insert(0, 'b') 
      fnlist.append(f) 
     else: 
      fnlist.append(x[i]) 
      i += 1 
return fnlist 

print lets_parse() 

Nota l'uso di globals. Un certo numero di critici potrebbe obiettare su di esso come cattivo stile di codifica.

+0

In effetti, è uno stile di codifica errato. Nella "ricorsione reale" non è necessario utilizzare variabili globali, il risultato viene passato come parametri e valori di ritorno della funzione ricorsiva. –

0
import ast  
mylist = '[a, a, a, b, a, a, b, a, c, a, b, a, a, c, a, c, a]' 
mylist = mylist.replace('a','"a"') 
mylist = mylist.replace('b','["b"') 
mylist = mylist.replace('c','"c"]') 
print ast.literal_eval(mylist) 
#Output: 
['a', 'a', 'a', ['b', 'a', 'a', ['b', 'a', 'c'], 'a', ['b', 'a', 'a', 'c'], 'a', 'c'], 'a'] 
1

Ci sono molto belle risposte a questa domanda, mi è particolarmente piaciuto soluzione ricorsiva thg435 di utilizzare generatori e soluzione iterativa di Marcin che aggiunge elementi alle liste di riferimento.

Ho anche scoperto che alcune soluzioni modificano l'elenco di input o utilizzano lo stato globale. Questo, IMHO, va contro il vero spirito di una soluzione ricorsiva.Di seguito è il mio tentativo di una soluzione puramente funzionale, ricorsiva in Python - concessa, ci sono modi molto più idiomatici ed efficaci per risolvere questo problema, ma ho voluto scrivere una risposta come l'avrei scritta in un linguaggio di programmazione puramente funzionale:

# lst: the list to be processed 
# acc: accumulated result 
# stk: temporary stack 
def process(lst, acc, stk): 
    if not lst: 
     return acc 
    elif lst[0] == 'b': 
     return process(lst[1:], [lst[0]], [acc] + stk) 
    elif lst[0] == 'c': 
     return process(lst[1:], stk[0] + [acc + [lst[0]]], stk[1:]) 
    else: 
     return process(lst[1:], acc + [lst[0]], stk) 

lst = ['a', 'a', 'a', 'b', 'a', 'a', 'b', 'a', 'c', 'a', 'b', 'a', 'a', 'c', 'a', 'c', 'a'] 
process(lst, [], []) 
> ['a', 'a', 'a', ['b', 'a', 'a', ['b', 'a', 'c'], 'a', ['b', 'a', 'a', 'c'], 'a', 'c'], 'a'] 

alcuni dettagli da notare:

  • non faccio uso di variabili locali o variabili globali, solo i parametri di funzione per tenere traccia dello stato
  • non faccio uso di operatori di assegnazione
  • Nessun iteratore o gabinetto ps è usato per attraversare la lista di input, solo ricorsione
  • È una soluzione ricorsiva di coda, anche se è irrilevante in Python
  • Sono utilizzate solo espressioni; operazioni come append o extend (che restituiscono None) sono evitati
  • mancanza di liste mai modificati (compresa la lista di input), invece vengono creati nuovi elenchi, se necessario (utilizzando fette matrice per questo)
  • E 'una piuttosto breve ed elegante soluzione, ma che potrebbe essere un parere soggettivo :)
Problemi correlati