2009-05-27 8 views
98

Vorrei passare in rassegna un elenco controllando ogni elemento con quello successivo.Come eseguire il loop di tutto tranne l'ultimo elemento di un elenco?

C'è un modo in cui posso scorrere tutto tranne l'ultimo elemento usando x in y? Preferirei farlo senza usare gli indici se possibile.

Nota

freespace risposto alla mia domanda effettiva, che è il motivo per cui ho accettato la risposta, ma SilentGhost ha risposto alla domanda avrei dovuto chiedere.

Scuse per la confusione.

risposta

196
for x in y[:-1] 

Se y è un generatore, il precedente non funzionerà.

+0

Questo risponde alla mia domanda, grazie, ma ho dimenticato di chiedere come ottenere l'oggetto dopo x. È possibile? –

+0

Credo che una dichiarazione "else" ti permetta di gestire ciò che accade dopo il ciclo, semplicemente non dimenticarti di impostare x sull'ultimo elemento. – nevets1219

+2

- 1 Non penso che risponda alla domanda. Non sta confrontando ogni articolo con il prossimo. - odwl 0 secondi fa – odwl

18

Se si desidera ottenere tutti gli elementi della coppia di sequenze saggia, utilizzare questo approccio (la funzione pairwise è dagli esempi nel modulo itertools).

from itertools import tee, izip, chain 

def pairwise(seq): 
    a,b = tee(seq) 
    b.next() 
    return izip(a,b) 

for current_item, next_item in pairwise(y): 
    if compare(current_item, next_item): 
     # do what you have to do 

Se è necessario confrontare l'ultimo valore per un valore speciale, catena che valore alla fine

for current, next_item in pairwise(chain(y, [None])): 
+0

si noti che l'uso di next per ombre nome variabile incorporato – SilentGhost

+0

Personalmente non mi dispiace ombreggiare i builtin meno usati quando l'ambito della variabile è piccolo e il nome è buono per la leggibilità. Tuttavia modifica i nomi delle variabili per mantenere buone pratiche di codifica. –

4

se si intende il confronto voce n-esimo con n + 1 esimo elemento della lista si potrebbe anche fare con

>>> for i in range(len(list[:-1])): 
...  print list[i]>list[i+1] 

nota non c'è hard coding in corso lì. Questo dovrebbe essere ok se non ti senti diversamente.

+2

È possibile sostituire len (elenco [: - 1]) con len (elenco) - 1 per evitare una copia di elenco. Ed evita di usare una variabile chiamata lista ... –

37

il modo più semplice per confrontare la voce di sequenza con il seguente:

for i, j in zip(a, a[1:]): 
    # compare i (the current) to j (the following) 
+9

Questo risponde alla domanda che vorrei aver chiesto. Grazie –

+2

In realtà, è possibile omettere la prima sezione, poiché zip tronca la lista più lunga per la lunghezza del più breve. Questo ti farà risparmiare una creazione di lista. (Nel caso abbiate a che fare con elenchi enormi, ma in questo caso dovreste seguire l'approccio di Ants Aasma, che non copia nulla.) – bayer

+0

grazie, di solito, inutile, sembra davvero più pulito. – SilentGhost

0

confrontare ogni elemento con il successivo in un iteratore senza istanziare un elenco:

import itertools 
it = (x for x in range(10)) 
data1, data2 = itertools.tee(it) 
data2.next() 
for a, b in itertools.izip(data1, data2): 
    print a, b 
+1

questo è esattamente ciò che è stato suggerito da Ants Aasma http://stackoverflow.com/questions/914715/python-looping-through-all-but-the-last-item-of-a-list/914786#914786 – SilentGhost

0

questo risponde quello che il OP avrebbe dovuto chiedere, cioè attraversare un elenco di elementi consecutivi (eccellente SilentGhost risposta), ancora generalizzato per qualsiasi gruppo (n-grammo): 2, 3, ... n:

zip(*(l[start:] for start in range(0, n)))

Esempi:

l = range(0, 4) # [0, 1, 2, 3] 

list(zip(*(l[start:] for start in range(0, 2)))) # == [(0, 1), (1, 2), (2, 3)] 
list(zip(*(l[start:] for start in range(0, 3)))) # == [(0, 1, 2), (1, 2, 3)] 
list(zip(*(l[start:] for start in range(0, 4)))) # == [(0, 1, 2, 3)] 
list(zip(*(l[start:] for start in range(0, 5)))) # == [] 

spiegazioni:

  • l[start:] genera elenco aa/generatore partire dall'indice start
  • *list o *generator: passa tutto elem Ent alla funzione di inclusione zip come se fosse stato scritto zip(elem1, elem2, ...)

Nota:

per quanto ne so, questo codice è come pigri come può essere. Non testato.

Problemi correlati