Come scorrere tutti tranne l'ultimo elemento di un elenco?


160

Vorrei scorrere un elenco per verificare ogni elemento rispetto a quello che lo segue.

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

Nota

freespace ha risposto alla mia vera domanda, motivo per cui ho accettato la risposta, ma SilentGhost ha risposto alla domanda che avrei dovuto porre.

Scuse per la confusione.

Risposte:


316
for x in y[:-1]

Se yè un generatore, quindi quanto sopra non funzionerà.


Questo risponde alla mia domanda, grazie, ma ho dimenticato di chiedere come avrei ottenuto l'oggetto dopo x. È possibile?
David Sykes,

3
- 1 Non credo che risponda alla domanda. Non sta confrontando ogni elemento con quello successivo. - odwl 0 secondi fa
odwl

4
Penso di averlo fatto. L'autore ha detto che gli piacerebbe fare X, poi ha chiesto come può fare Y. Ho risposto come può fare Y. Il fatto che abbia accettato la mia risposta indicherebbe che ho risposto alla domanda che aveva posto, se non alla domanda che voleva davvero fare. Asker è invitato a retrocedere questa risposta.
spazio libero

7
Solo perché l'OP avrebbe dovuto porre un'altra domanda nella prima, non significa che la sua domanda e questa risposta non siano molto utili agli altri. +1
Prof. Falken,

1
Dici che questo non funziona per i generatori. Qual è l'alternativa quando yè un generatore?
Joost,

50

il modo più semplice per confrontare l'elemento della sequenza con il seguente:

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

15
Questo risponde alla domanda che vorrei aver posto. Grazie
David Sykes,

3
In realtà, puoi omettere la prima sezione, poiché zip tronca l'elenco più lungo alla lunghezza del più breve. Questo ti salverà una creazione dell'elenco. (Nel caso in cui tu abbia a che fare con liste enormi. Ma in quel caso, dovresti seguire l'approccio di Ants Aasma, che non copia nulla.)
Bayer,

19

Se vuoi ottenere tutti gli elementi nella coppia di sequenze saggia, usa questo approccio (la funzione pairwise proviene 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 devi confrontare l'ultimo valore con un valore speciale, concatenalo alla fine

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

si noti che l'uso di next per le ombre dei nomi delle variabili integrate
SilentGhost

1
Personalmente non mi dispiace oscurare i builtin meno usati quando l'ambito della variabile è piccolo e il nome è buono per la leggibilità. Tuttavia ha modificato i nomi delle variabili per mantenere buone pratiche di codifica.
Ants Aasma,

5

se intendevi confrontare l'ennesimo elemento con n + 1 ° elemento nell'elenco, potresti anche fare

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

nota che non c'è nessuna codifica dura in corso lì. Questo dovrebbe andare bene a meno che non ti senta diversamente.


3
È possibile sostituire len (elenco [: - 1]) con len (elenco) - 1 per evitare una copia dell'elenco. Evita di usare una variabile chiamata list ...
Remy Blank,

2

Per confrontare ciascun elemento con il successivo in un iteratore senza creare un'istanza di 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

2
Questo è esattamente ciò che è stato suggerito da Formiche Aasma stackoverflow.com/questions/914715/...
SilentGhost

1

Questo risponde a ciò che l'OP avrebbe dovuto chiedere , ovvero attraversare un elenco confrontando elementi consecutivi (eccellente risposta SilentGhost ), ma 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 un elenco / generatore a partire dall'indice start
  • *listoppure *generator: passa tutti gli elementi alla funzione che racchiude zipcome se fosse stata scrittazip(elem1, elem2, ...)

Nota:

AFAIK, questo codice è pigro come può essere. Non testato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.