¿Cómo recorrer todo menos el último elemento de una lista?

160

Me gustaría recorrer una lista que compara cada elemento con el siguiente.

¿Hay alguna forma de recorrer todo menos el último elemento usando para x en y? Preferiría hacerlo sin usar índices si puedo.

Nota

freespace respondió mi pregunta real, por eso acepté la respuesta, pero SilentGhost respondió la pregunta que debería haber hecho.

Disculpas por la confusión.

David Sykes
fuente

Respuestas:

316
for x in y[:-1]

Si yes un generador, entonces lo anterior no funcionará.

espacio libre
fuente
Eso responde a mi pregunta, gracias, pero olvidé preguntar cómo obtendría el artículo después de x. es posible?
David Sykes
3
- 1 No creo que eso responda la pregunta. No es comparar cada elemento con el siguiente. - odwl hace 0 segundos
odwl
44
Creo que lo hice. El autor dijo que le gustaría hacer X, luego preguntó cómo puede hacer Y. Respondí cómo puede hacer Y. Que él aceptara mi respuesta indicaría que respondí la pregunta que hizo, si no la pregunta que realmente quería hacer. Asker puede degradar esta respuesta.
espacio libre
77
El hecho de que el OP debería haber hecho otra pregunta en la primera, no significa que su pregunta y esta respuesta no sean muy útiles para otros. +1
Prof. Falken
1
Usted menciona que esto no funciona para los generadores. ¿Cuál es la alternativa cuando yes un generador?
Joost
50

La forma más fácil de comparar el elemento de secuencia con lo siguiente:

for i, j in zip(a, a[1:]):
     # compare i (the current) to j (the following)
SilentGhost
fuente
15
Esto responde a la pregunta que desearía haber hecho. Gracias
David Sykes
3
En realidad, puede omitir la primera porción, ya que zip trunca la lista más larga a la longitud de la más corta. Esto le ahorrará una creación de lista. (Solo en caso de que estés lidiando con grandes listas. Pero en ese caso, debes seguir el enfoque de Ants Aasma, que no copia nada)
Bayer
19

Si desea obtener todos los elementos en la secuencia de pares sabios, utilice este enfoque (la función por pares es de los ejemplos en el módulo 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

Si necesita comparar el último valor con algún valor especial, encadene ese valor hasta el final

for current, next_item in pairwise(chain(y, [None])):
Hormigas Aasma
fuente
Tenga en cuenta, que el uso de sombras al lado de nombres de variables incorporadas
SilentGhost
1
Personalmente, no me importa sombrear las construcciones menos utilizadas cuando el alcance de la variable es pequeño y el nombre es bueno para la legibilidad. Sin embargo, editó los nombres de las variables para mantener buenas prácticas de codificación.
Ants Aasma
5

si quisieras comparar el enésimo elemento con n + 1º elemento en la lista, también podrías hacerlo con

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

tenga en cuenta que no hay codificación dura allí. Esto debería estar bien a menos que sientas lo contrario.

Codificador perpetuo
fuente
3
Puede reemplazar len (list [: - 1]) con len (list) - 1 para evitar una copia de la lista. Y evitar el uso de una variable lista llamada ...
blanco Remy
2

Para comparar cada elemento con el siguiente en un iterador sin crear una instancia de una lista:

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
Odwl
fuente
2
eso es exactamente lo que sugirió Ants Aasma stackoverflow.com/questions/914715/…
SilentGhost
1

Esto responde a lo que el OP debería haber preguntado , es decir, recorrer una lista que compara elementos consecutivos (excelente respuesta de SilentGhost ), pero generalizada para cualquier grupo ( n-gramo ): 2, 3, ... n:

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

Ejemplos:

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)))) # == []

Explicaciones:

  • l[start:] genera una lista / generador a partir del índice start
  • *listo *generator: pasa todos los elementos a la función de cierre zipcomo si se hubiera escritozip(elem1, elem2, ...)

Nota:

AFAIK, este código es tan vago como puede ser. No probado.

juanmirocks
fuente