2010-07-12 20 views
6

In python, come posso dividere una lunga lista in una lista di liste ovunque mi imbatto '-'. Per esempio, come posso convertire:una lista> un elenco di liste

['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] 

a

[['1', 'a', 'b'],['2','c','d'],['3','123','e'],['4']] 

Molte grazie in anticipo.

risposta

17
In [17]: import itertools 
# putter around 22 times 
In [39]: l=['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] 

In [40]: [list(g) for k,g in itertools.groupby(l,'---'.__ne__) if k] 
Out[40]: [['1', 'a', 'b'], ['2', 'c', 'd'], ['3', '123', 'e'], ['4']] 
+0

+1 Nice (non ho pensato subito a 'itertools.groupby' qui, ma si adatta davvero al conto) – ChristopheD

+0

Grazie per la risposta. C'è un modo per controllare x == '---' nella riga precedente con un'espressione regolare (qualcosa come x == re.match ('-'))? Molte grazie – DGT

+0

Sì, si potrebbe usare qualcosa come '[lista (g) per k, g in itertools.groupby (l, lambda x: re.match ('---', x)) se non k]'. L'espressione 're.match (...)' restituisce None quando 'x' non corrisponde al modello. Quindi 'k' è' None' per gli elementi che vuoi mantenere. Quindi ho cambiato la condizione in "se non k". – unutbu

4
import itertools 

l = ['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] 
r = [] 

i = iter(l) 
while True: 
    a = [x for x in itertools.takewhile(lambda x: x != '---', i)] 
    if not a: 
    break 
    r.append(a) 
print r 

# [['1', 'a', 'b'], ['2', 'c', 'd'], ['3', '123', 'e'], ['4']] 
+0

+1 Questo mi piace meglio della mia soluzione simile (lo eliminerò a breve) a causa dell'efficiente approccio "iter" (lo si consuma solo una volta). Ma probabilmente stai per sostituire 'for j in range (7)' con 'while True' per gestire lunghezze arbitrarie. – ChristopheD

+0

@ChristopheD: Sì, corretto. –

-1

E 'stato un po' che non ho fatto alcun pitone così la mia sintassi sta per essere lontano, ma un ciclo semplice dovrebbe essere sufficiente.

Tenere traccia degli indici in due numeri

firstList = ['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] 
listIndex = 0 
itemIndex = 0 
ii = 0 
foreach item in firstList 
    if(firstList[ii] == '---') 
    listIndex = listIndex + 1 
    itemIndex = 0 
    ii = ii + 1 
    else secondList[listIndex][itemIndex] = firstList[ii] 
1
import itertools 

a = ['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] 
b = [list(x[1]) for x in itertools.groupby(a, '---'.__eq__) if not x[0]] 

print b  # or print(b) in Python 3 

risultato è

[['1', 'a', 'b'], ['2', 'c', 'd'], ['3', '123', 'e'], ['4']] 
0

Ecco una soluzione senza itertools:

def foo(input): 
    output = [] 
    currentGroup = [] 
    for value in input: 
     if '-' in value: #if we should break on this element 
      currentGroup.append(value) 
     elif currentGroup: 
      output.append(currentGroup) 
      currentGroup = [] 
    if currentGroup: 
     output.append(currentGroup) #appends the rest if not followed by separator  
    return output 

print (foo (['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'])) 
+1

Oltre una certa soglia, la leggibilità è relativa. Mi sembra una grande massa di codice. –

+1

Utilizzo (1) 'value.find ('-') == -1' invece di' '-' in value' (2) camelCase (2) parentesi ridondanti in '(el) se' a volte (3) spazi estranei tra parentesi qualche volta (4) affermazione abbastanza lunga da far sì che SO inserisca la barra di scorrimento orizzontale di ferschlugginer (5) senza spazio dopo la virgola a volte mi fa sembrare un gran casino di codice fugly per me. –

+0

Hai ragione entrambi. Codice e descrizione modificati. :) –

1

Ecco un modo per farlo :

lst=['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] 
indices=[-1]+[i for i,x in enumerate(lst) if x=='---']+[len(lst)] 
answer=[lst[indices[i-1]+1:indices[i]] for i in xrange(1,len(indices))] 
print answer 

Fondamentalmente, questo trova le posizioni della stringa "---" nell'elenco e quindi divide l'elenco di conseguenza.

Problemi correlati