Recorrer una lista en orden inverso en Python

Así que puedo comenzar desde len(collection) y terminar en collection[0] .

EDITAR: Lo siento, olvidé mencionar que también quiero poder acceder al índice de bucle.

Use la función reversed() incorporada:

 >>> a = ["foo", "bar", "baz"] >>> for i in reversed(a): ... print(i) ... baz bar foo 

Para acceder también al índice original, use enumerate() en su lista antes de pasarlo a reversed() :

 >>> for i, e in reversed(list(enumerate(a))): ... print(i, e) ... 2 baz 1 bar 0 foo 

Como enumerate() devuelve un generador y los generadores no se pueden revertir, primero debe convertirlo en una list .

Tu puedes hacer:

 for item in my_list[::-1]: print item 

(O lo que quieras hacer en el bucle for).

El segmento [::-1] invierte la lista en el bucle for (pero en realidad no modificará su lista “permanentemente”).

Si necesita el índice de bucle y no desea recorrer la lista completa dos veces, o usar memoria adicional, escribiría un generador.

 def reverse_enum(L): for index in reversed(xrange(len(L))): yield index, L[index] L = ['foo', 'bar', 'bas'] for index, item in reverse_enum(L): print index, item 

Se puede hacer así:

  para i en rango (len (colección) -1, -1, -1):
     colección de impresión [i]

     # print (colección [i]) para python 3. +

Entonces, tu suposición fue bastante cercana 🙂 Un poco incómodo, pero básicamente dice: comienza con 1 menos que len(collection) , continúa hasta que llegues justo antes de -1, por pasos de -1.

Para tu información, la función de help es muy útil, ya que te permite ver los documentos de algo desde la consola de Python, por ejemplo:

help(range)

La función incorporada reversed es útil:

 for item in reversed(sequence): 

La documentación para anular explica sus limitaciones.

Para los casos en los que tengo que recorrer una secuencia en sentido inverso junto con el índice (por ejemplo, para modificaciones in situ que cambian la longitud de la secuencia), tengo esta función definida en mi módulo codeutil:

 import itertools def reversed_enumerate(sequence): return itertools.izip( reversed(xrange(len(sequence))), reversed(sequence), ) 

Éste evita crear una copia de la secuencia. Obviamente, las limitaciones reversed todavía se aplican.

 >>> l = ["a","b","c","d"] >>> l.reverse() >>> l ['d', 'c', 'b', 'a'] 

O

 >>> print l[::-1] ['d', 'c', 'b', 'a'] 

¿Qué tal sin volver a crear una nueva lista, puede hacerlo indexando:

 >>> foo = ['1a','2b','3c','4d'] >>> for i in range(len(foo)): ... print foo[-(i+1)] ... 4d 3c 2b 1a >>> 

O

 >>> length = len(foo) >>> for i in range(length): ... print foo[length-i-1] ... 4d 3c 2b 1a >>> 

Me gusta el enfoque del generador de una sola línea:

 ((i, sequence[i]) for i in reversed(xrange(len(sequence)))) 

Además, puede usar las funciones “rango” o “contar”. Como sigue:

 a = ["foo", "bar", "baz"] for i in range(len(a)-1, -1, -1): print(i, a[i]) 3 baz 2 bar 1 foo 

También puede usar “contar” de itertools de la siguiente manera:

 a = ["foo", "bar", "baz"] from itertools import count, takewhile def larger_than_0(x): return x > 0 for x in takewhile(larger_than_0, count(3, -1)): print(x, a[x-1]) 3 baz 2 bar 1 foo 

Use list.reverse() y luego itere como lo haría normalmente.

http://docs.python.org/tutorial/datastructures.html

 def reverse(spam): k = [] for i in spam: k.insert(0,i) return "".join(k) 

Para lo que sea que valga la pena, puedes hacerlo así también. muy simple.

 a = [1, 2, 3, 4, 5, 6, 7] for x in xrange(len(a)): x += 1 print a[-x] 

Las otras respuestas son buenas, pero si quieres hacerlo como estilo de comprensión de lista

 collection = ['a','b','c'] [item for item in reversed( collection ) ] 

use la función incorporada reversed() para el objeto de secuencia, este método tiene el efecto de todas las secuencias

enlace de referencia más detallado

También puedes usar un bucle while:

 i = len(collection)-1 while i>=0: value = collection[i] index = i i-=1 

Un enfoque fácil es:

 for i in range(1,len(arr)+1): print(arr[-i]) 

Puedes usar un índice negativo en un bucle ordinario:

 >>> collection = ["ham", "spam", "eggs", "baked beans"] >>> for i in range(1, len(collection) + 1): ... print(collection[-i]) ... baked beans eggs spam ham 

Para acceder al índice como si estuviera iterando hacia adelante sobre una copia invertida de la colección, use i - 1 :

 >>> for i in range(1, len(collection) + 1): ... print(i-1, collection[-i]) ... 0 baked beans 1 eggs 2 spam 3 ham 

Para acceder al índice original sin reversión, use len(collection) - i :

 >>> for i in range(1, len(collection) + 1): ... print(len(collection)-i, collection[-i]) ... 3 baked beans 2 eggs 1 spam 0 ham 

Una forma expresiva de lograr el reverse(enumerate(collection)) en python 3:

 zip(reversed(range(len(collection))), reversed(collection)) 

en python 2:

 izip(reversed(xrange(len(collection))), reversed(collection)) 

No estoy seguro de por qué no tenemos una taquigrafía para esto, por ejemplo:

 def reversed_enumerate(collection): return zip(reversed(range(len(collection))), reversed(collection)) 

o por qué no tenemos reversed_range()

 a = ["foo", "bar", "baz"] print a[::~0] 

otra manera de resolver este problema, este código se ejecuta decrementado para bucle

Si necesita el índice y su lista es pequeña, la forma más legible es hacerlo reversed(list(enumerate(your_list))) como dice la respuesta aceptada. Pero esto crea una copia de su lista, por lo tanto, si su lista está ocupando una gran parte de su memoria, tendrá que restar el índice devuelto por enumerate(reversed()) de len()-1 .

Si solo necesitas hacerlo una vez:

 a = ['b', 'd', 'c', 'a'] for index, value in enumerate(reversed(a)): index = len(a)-1 - index do_something(index, value) 

o si necesita hacer esto varias veces, debe usar un generador:

 def enumerate_reversed(lyst): for index, value in enumerate(reversed(lyst)): index = len(lyst)-1 - index yield index, value for index, value in enumerate_reversed(a): do_something(index, value) 

La función inversa es útil aquí:

 myArray = [1,2,3,4] myArray.reverse() for x in myArray: print x 

Para usar índices negativos: comience en -1 y retroceda por -1 en cada iteración.

 >>> a = ["foo", "bar", "baz"] >>> for i in range(-1, -1*(len(a)+1), -1): ... print i, a[i] ... -1 baz -2 bar -3 foo 

Una forma sencilla:

 n = int(input()) arr = list(map(int, input().split())) for i in reversed(range(0, n)): print("%d %d" %(i, arr[i])) 
 input_list = ['foo','bar','baz'] for i in range(-1,-len(input_list)-1,-1) print(input_list[i]) 

Creo que esta es también una forma sencilla de hacerlo … lea desde el final y siga disminuyendo hasta la longitud de la lista, ya que nunca ejecutamos el índice “final”, por lo tanto, se agrega -1 también

Suponiendo que la tarea es encontrar el último elemento que satisface alguna condición en una lista (es decir, primero al mirar hacia atrás), obtengo los siguientes números:

 >>> min(timeit.repeat('for i in xrange(len(xs)-1,-1,-1):\n if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8)) 4.6937971115112305 >>> min(timeit.repeat('for i in reversed(xrange(0, len(xs))):\n if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8)) 4.809093952178955 >>> min(timeit.repeat('for i, x in enumerate(reversed(xs), 1):\n if 128 == x: break', setup='xs, n = range(256), 0', repeat=8)) 4.931743860244751 >>> min(timeit.repeat('for i, x in enumerate(xs[::-1]):\n if 128 == x: break', setup='xs, n = range(256), 0', repeat=8)) 5.548468112945557 >>> min(timeit.repeat('for i in xrange(len(xs), 0, -1):\n if 128 == xs[i - 1]: break', setup='xs, n = range(256), 0', repeat=8)) 6.286104917526245 >>> min(timeit.repeat('i = len(xs)\nwhile 0 < i:\ni -= 1\n if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8)) 8.384078979492188 

Entonces, la opción más fea xrange(len(xs)-1,-1,-1) es la más rápida.

Si no te importa que el índice sea negativo, puedes hacer:

 >>> a = ["foo", "bar", "baz"] >>> for i in range(len(a)): ... print(~i, a[~i])) -1 baz -2 bar -3 foo