Entonces puedo comenzar len(collection)
y terminar collection[0]
.
También quiero poder acceder al índice de bucle.
Entonces puedo comenzar len(collection)
y terminar collection[0]
.
También quiero poder acceder al índice de bucle.
Respuestas:
Use la reversed()
función incorporada:
>>> a = ["foo", "bar", "baz"]
>>> for i in reversed(a):
... print(i)
...
baz
bar
foo
Para acceder también al índice original, úselo 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, debe convertirlo en un list
primero.
reversed()
no modifica la lista. reversed()
no hace una copia de la lista (de lo contrario, requeriría O (N) de memoria adicional). Si necesita modificar la lista, use alist.reverse()
; si necesita una copia de la lista en orden inverso, use alist[::-1]
.
Tu puedes hacer:
for item in my_list[::-1]:
print item
(O lo que quieras hacer en el bucle for.)
El [::-1]
segmento invierte la lista en el bucle for (pero en realidad no modificará su lista "permanentemente").
[::-1]
crea una copia superficial, por lo tanto, no cambia la matriz ni "permanentemente" ni "temporal".
0
, probablemente -1
, por lo que termina al principio ) y paso : -1
(itera hacia atrás a través de la lista, 1
elemento a la vez).
reversed()
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
reversed(xrange(len(L)))
produce los mismos índices que xrange(len(L)-1, -1, -1)
.
for index, item in enumerate(reversed(L)): print len(L)-1-index, item
Se puede hacer así:
para i en rango (len (colección) -1, -1, -1): colección impresa [i] # print (colección [i]) para python 3. +
Entonces su suposición fue bastante cercana :) Un poco incómodo pero básicamente dice: comience con 1 menos que len(collection)
, continúe hasta llegar justo antes de -1, en pasos de -1.
Para su información, la help
función es muy útil ya que le permite ver los documentos de algo de la consola de Python, por ejemplo:
help(range)
-1
. Solo diríareversed(xrange(len(collection)))
La reversed
función integrada es útil:
for item in reversed(sequence):
La documentación para revertir explica sus limitaciones.
Para los casos en los que tengo que caminar una secuencia en reversa junto con el índice (por ejemplo, para modificaciones en el lugar 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 reversed
limitaciones aún se aplican.
¿Qué tal si no recrea 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
>>>
Además, puede usar las funciones "rango" o "conteo". 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
3 foo\n2 bar\n1 baz
Use list.reverse()
y luego repita como lo haría normalmente.
Una forma expresiva de lograr 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 abreviatura para esto, por ejemplo:
def reversed_enumerate(collection):
return zip(reversed(range(len(collection))), reversed(collection))
o por qué no tenemos reversed_range()
Si necesita el índice y su lista es pequeña, la forma más fácil de leer es hacer lo reversed(list(enumerate(your_list)))
que dice la respuesta aceptada. Pero esto crea una copia de su lista, por lo que si su lista está ocupando una gran parte de la memoria que tendrá que restar el índice devuelve enumerate(reversed())
a 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
Puede usar un índice negativo en un ciclo for 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 no invertido, 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
Creo que la forma más elegante es transformar enumerate
y reversed
usar el siguiente generador
(-(ri+1), val) for ri, val in enumerate(reversed(foo))
que genera un reverso del enumerate
iterador
Ejemplo:
foo = [1,2,3]
bar = [3,6,9]
[
bar[i] - val
for i, val in ((-(ri+1), val) for ri, val in enumerate(reversed(foo)))
]
Resultado:
[6, 4, 2]
Las otras respuestas son buenas, pero si quieres hacer una lista de estilo de comprensión
collection = ['a','b','c']
[item for item in reversed( collection ) ]
input_list = ['foo','bar','baz']
for i in range(-1,-len(input_list)-1,-1)
print(input_list[i])
Creo que esta también es una forma simple de hacerlo ... leer desde el final y seguir decrementando hasta la longitud de la lista, ya que nunca ejecutamos el índice "final", por lo tanto, agregamos -1 también
Asumiendo que la tarea es encontrar el último elemento que satisfaga alguna condición en una lista (es decir, primero cuando se mira 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:\n i -= 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.