È considerata una cattiva forma chiamare "next" nella sequenza di input di una list comprehension?

2

Voglio estrarre le righe da un flusso precedute dal carattere L . La comprensione della lista qui sotto fa il lavoro, ma chiama next sul flusso all'interno della comprensione in un modo che non ho mai visto prima. È considerato una cattiva forma?

clauses = [
    list(map(int, next(stream)))
    for line in stream
    if line == 'L'
]

Il next avanza la sequenza in modo che le righe che seguono L linee non passino mai attraverso il predicato, il che viola il principio "non modificare mai una sequenza su cui stai iterando". Ma mi chiedo se questo caso potrebbe essere un'eccezione ...

    
posta Elliot Gorokhovsky 11.07.2018 - 05:07
fonte

1 risposta

2

Come per lo Zen di Python - l'esplicito è meglio che implicito. L'utilizzo di next() nell'espressione del generatore non è soddisfacente. Che dire del tuo generatore con tutta la logica in chiaro:

def take_one_after(iterable, sentinel):
    take = False
    for item in iterable:
        if item == sentinel:
            take = True
        elif take:
            take = False
            yield item


print(list(take_one_after(stream, 'L')))

(Nota, non faccio nulla con int , ecc.)

Inoltre, il modulo itertools può essere utile se vuoi un solo liner (es. usando tee per duplicare il flusso in due, consumare un elemento sul secondo flusso, poi zip entrambi i flussi in tuple e prontamente prendere la tupla invia elemento quando il primo è 'L' - questo è ciò che si qualifica come iterando in coppie di righe come per il commento di jonrsharpe, ma il codice potrebbe essere troppo criptico).

Gli iteratori possono essere concatenati per qualsiasi tipo di elaborazione e trasformati in elenchi solo alla fine dell'elaborazione.

    
risposta data 12.07.2018 - 11:11
fonte

Leggi altre domande sui tag