Le soluzioni fino ad ora riguardano solo gli elenchi e la maggior parte sta copiando l'elenco. Nella mia esperienza molte volte non è possibile.
Inoltre, non si occupano del fatto che puoi avere elementi ripetuti nell'elenco.
Il titolo della tua domanda dice " Valori precedenti e successivi all'interno di un ciclo ", ma se esegui la maggior parte delle risposte qui all'interno di un ciclo, finirai per iterare di nuovo l'intero elenco su ogni elemento per trovarlo.
Quindi ho appena creato una funzione che. utilizzando il itertoolsmodulo, divide e affetta l'iterabile e genera tuple con gli elementi precedente e successivo insieme. Non esattamente quello che fa il tuo codice, ma vale la pena dare un'occhiata, perché probabilmente può risolvere il tuo problema.
from itertools import tee, islice, chain, izip
def previous_and_next(some_iterable):
prevs, items, nexts = tee(some_iterable, 3)
prevs = chain([None], prevs)
nexts = chain(islice(nexts, 1, None), [None])
return izip(prevs, items, nexts)
Quindi usalo in un ciclo e avrai gli elementi precedenti e successivi in esso:
mylist = ['banana', 'orange', 'apple', 'kiwi', 'tomato']
for previous, item, nxt in previous_and_next(mylist):
print "Item is now", item, "next is", nxt, "previous is", previous
I risultati:
Item is now banana next is orange previous is None
Item is now orange next is apple previous is banana
Item is now apple next is kiwi previous is orange
Item is now kiwi next is tomato previous is apple
Item is now tomato next is None previous is kiwi
Funzionerà con qualsiasi elenco di dimensioni (perché non copia l'elenco) e con qualsiasi iterabile (file, set, ecc.). In questo modo puoi semplicemente iterare sulla sequenza e avere gli elementi precedenti e successivi disponibili all'interno del ciclo. Non è necessario cercare di nuovo l'elemento nella sequenza.
Una breve spiegazione del codice:
tee viene utilizzato per creare in modo efficiente 3 iteratori indipendenti sulla sequenza di input
chaincollega due sequenze in una; è usato qui per aggiungere una sequenza [None]di un singolo elemento aprevs
isliceviene utilizzato per creare una sequenza di tutti gli elementi tranne il primo, quindi chainviene utilizzato per aggiungere un Nonealla sua fine
- Ora ci sono 3 sequenze indipendenti basate su
some_iterablequesto aspetto come:
prevs: None, A, B, C, D, E
items: A, B, C, D, E
nexts: B, C, D, E, None
- infine
izipè usato per cambiare 3 sequenze in una sequenza di terzine.
Nota che si izipinterrompe quando una sequenza di input viene esaurita, quindi l'ultimo elemento di prevsverrà ignorato, il che è corretto: non esiste un elemento tale che l'ultimo elemento sarebbe il suo prev. Potremmo provare a togliere gli ultimi elementi da prevsmaizip il comportamento di rende ridondante
Si noti inoltre che tee, izip, islicee chainprovengono dal itertoolsmodulo; agiscono sulle loro sequenze di input al volo (pigramente), il che li rende efficienti e non introduce la necessità di avere l'intera sequenza in memoria contemporaneamente e in qualsiasi momento.
In python 3, mostrerà un errore durante l'importazione izip, puoi usare al zipposto di izip. Non è necessario importare zip, è predefinito in python 3- source