Domanda Python che divide un elenco in base a una parola delimitatore


Ho una lista contenente vari valori di stringa. Voglio dividere la lista ogni volta che vedo WORD. Il risultato sarà una lista di liste (che saranno le sottoliste della lista originale) contenenti esattamente un'istanza di WORD Posso farlo usando un ciclo ma c'è a più pitonico modo di farlo?

Esempio = ['A', 'WORD', 'B' , 'C' , 'WORD' , 'D']

risultato = [['A'], ['WORD','B','C'],['WORD','D']]

Questo è quello che ho provato, ma in realtà non raggiunge ciò che voglio dal momento che lo farà WORD in una lista diversa che dovrebbe essere in:

def split_excel_cells(delimiter, cell_data):

    result = []

    temp = []

    for cell in cell_data:
        if cell == delimiter:
            temp.append(cell)
            result.append(temp)
            temp = []
        else:
            temp.append(cell)

    return result

15
2018-03-12 09:45


origine


risposte:


Vorrei usare un generatore:

def group(seq, sep):
    g = []
    for el in seq:
        if el == sep:
            yield g
            g = []
        g.append(el)
    yield g

ex = ['A', 'WORD', 'B' , 'C' , 'WORD' , 'D']
result = list(group(ex, 'WORD'))
print(result)

Questo stampa

[['A'], ['WORD', 'B', 'C'], ['WORD', 'D']]

Il codice accetta qualsiasi iterabile e produce un iterabile (che non lo è avere per appiattirsi in una lista se non si desidera).


10
2018-03-12 09:54



import itertools

lst = ['A', 'WORD', 'B' , 'C' , 'WORD' , 'D']
w = 'WORD'

spl = [list(y) for x, y in itertools.groupby(lst, lambda z: z == w) if not x]

questo crea una lista divisa senza delimitatori, il che mi sembra più logico:

[['A'], ['B', 'C'], ['D']]

Se insisti sui delimitatori per essere inclusi, questo dovrebbe fare il trucco:

spl = [[]]
for x, y in itertools.groupby(lst, lambda z: z == w):
    if x: spl.append([])
    spl[-1].extend(y)

13
2018-03-12 10:14



La soluzione di @ NPE mi sembra molto pitonica. Questo è un altro usando itertools:

from itertools import izip, chain
example = ['A', 'WORD', 'B' , 'C' , 'WORD' , 'D']
indices = [i for i,x in enumerate(example) if x=="WORD"]
pairs = izip(chain([0], indices), chain(indices, [None]))
result = [example[i:j] for i, j in pairs]

Questo codice si basa principalmente su questa risposta.


1
2018-03-12 10:03



Dato

import more_itertools as mit


iterable = ["A", "WORD", "B" , "C" , "WORD" , "D"]
pred = lambda x: x == "WORD"

Codice

list(mit.split_before(iterable, pred))
# [['A'], ['WORD', 'B', 'C'], ['WORD', 'D']]

more_itertools è una libreria di terze parti installabile via > pip install more_itertools.

Guarda anche split_at e split_after.


0
2017-07-14 00:06