¿Cómo se puede producir la siguiente lista range()
en Python?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
¿Cómo se puede producir la siguiente lista range()
en Python?
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Respuestas:
utilizar la reversed()
función:
reversed(range(10))
Es mucho más significativo.
Actualizar:
Si desea que sea una lista (como señaló btk):
list(reversed(range(10)))
Actualizar:
Si desea usar solo range
para lograr el mismo resultado, puede usar todos sus parámetros.range(start, stop, step)
Por ejemplo, para generar una lista [5,4,3,2,1,0]
, puede usar lo siguiente:
range(5, -1, -1)
Puede ser menos intuitivo, pero como mencionan los comentarios, esto es más eficiente y el uso correcto del rango para la lista inversa.
range(10)
, no range(9)
. Además, si desea una lista completa (para cortar, etc.), debe hacerlo list(reversed(range(10)))
.
reversed
no acepta generadores en general, pero acepta range
. ¿Por qué reversed(range(10000))
necesitaría asignar memoria para toda la lista? range
puede devolver un objeto que implementa el __reversed__
método que permite una iteración inversa eficiente?
Use la función incorporada 'rango'. La firma es range(start, stop, step)
. Esto produce una secuencia que produce números, comenzando start
y terminando si stop
se ha alcanzado, excluyendo stop
.
>>> range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> range(-2, 6, 2)
[-2, 0, 2, 4]
En Python 3, esto produce un range
objeto que no es una lista , que funciona efectivamente como una lista de solo lectura (pero usa mucha menos memoria, particularmente para grandes rangos).
help(range)
en un shell de Python, le dirá los argumentos. Son el número para comenzar, el número para terminar (exclusivo) y el paso a seguir, por lo que comienza en 9 y resta 1 hasta llegar a -1 (en ese punto se detiene sin regresar, por eso el rango termina en 0)
range(start, stop, step)
- comience en el número start
y produzca resultados a menos que stop
se haya alcanzado, moviéndose step
cada vez.
Para aquellos que estén interesados en la "eficiencia" de las opciones recopiladas hasta ahora ...
La respuesta de Jaime RGP me llevó a reiniciar mi computadora después de cronometrar la solución algo "desafiante" de Jason, literalmente, siguiendo mi propia sugerencia (a través de un comentario). Para ahorrarle a los curiosos el tiempo de inactividad, les presento aquí mis resultados (el peor primero):
La respuesta de Jason (tal vez solo una excursión al poder de la comprensión de la lista ):
$ python -m timeit "[9-i for i in range(10)]"
1000000 loops, best of 3: 1.54 usec per loop
Respuesta de martineau (legible si está familiarizado con la sintaxis de cortes extendidos ):
$ python -m timeit "range(10)[::-1]"
1000000 loops, best of 3: 0.743 usec per loop
La respuesta de Michał Šrajer (la aceptada, muy legible):
$ python -m timeit "reversed(range(10))"
1000000 loops, best of 3: 0.538 usec per loop
La respuesta de bene (la primera, pero muy incompleta en ese momento ):
$ python -m timeit "range(9,-1,-1)"
1000000 loops, best of 3: 0.401 usec per loop
La última opción es fácil de recordar usando la range(n-1,-1,-1)
notación de Val Neekman .
reverse
porque el método de rango puede devolver una lista invertida.Cuando tiene iteración sobre n elementos y desea reemplazar el orden de la lista que devuelve range(start, stop, step)
, debe usar el tercer parámetro de rango que lo identifica step
y establecerlo -1
, otros parámetros se ajustarán en consecuencia:
-1
(su valor anterior de stop - 1
, stop
era igual a 0
).n-1
.Entonces, el equivalente del rango (n) en orden inverso sería:
n = 10
print range(n-1,-1,-1)
#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(n))
La legibilidad a un lado, reversed(range(n))
parece ser más rápida que range(n)[::-1]
.
$ python -m timeit "reversed(range(1000000000))"
1000000 loops, best of 3: 0.598 usec per loop
$ python -m timeit "range(1000000000)[::-1]"
1000000 loops, best of 3: 0.945 usec per loop
Solo si alguien se preguntara :)
range(1000000000-1,-1,-1)
también?
timeit range(1000000000-1,-1,-1)
en la línea de comando, en cambio ve mis resultados :-)
El requisito en esta pregunta requiere un número list
entero de tamaño 10 en orden descendente. Entonces, produzcamos una lista en python.
# This meets the requirement.
# But it is a bit harder to wrap one's head around this. right?
>>> range(10-1, -1, -1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
# let's find something that is a bit more self-explanatory. Sounds good?
# ----------------------------------------------------
# This returns a list in ascending order.
# Opposite of what the requirement called for.
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# This returns an iterator in descending order.
# Doesn't meet the requirement as it is not a list.
>>> reversed(range(10))
<listreverseiterator object at 0x10e14e090>
# This returns a list in descending order and meets the requirement
>>> list(reversed(range(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
-1
Es exactamente este patrón el que lo hace fácil de mantener wrap one's head around this
. Hoy aprendí que si realmente tiene que ser eficiente , range(n-1, -1, -1)
úselo cuando atraviese un rango en orden inverso.
Puede imprimir números inversos con range () BIF Like,
for number in range ( 10 , 0 , -1 ) :
print ( number )
La producción será [10,9,8,7,6,5,4,3,2,1]
rango () - rango (inicio, fin, incremento / decremento) donde inicio es inclusivo, fin es exclusivo e incremento puede ser cualquier número y se comporta como un paso
La pregunta más frecuente es si es range(9, -1, -1)
mejor que reversed(range(10))
en Python 3. Las personas que han trabajado en otros idiomas con iteradores inmediatamente tienden a pensar que reverse () debe almacenar en caché todos los valores y luego regresar en orden inverso. La cosa es que el reversed()
operador de Python no funciona si el objeto es solo un iterador. El objeto debe tener uno de los dos siguientes para que funcione reverse ():
len()
e índices enteros a través de[]
__reversed__()
método implementado.Si intenta usar reverse () en un objeto que no tiene ninguno de los anteriores, obtendrá:
>>> [reversed((x for x in range(10)))]
TypeError: 'generator' object is not reversible
En resumen, Python reversed()
solo se entiende en objetos tipo matriz y, por lo tanto, debe tener el mismo rendimiento que la iteración directa.
¿Pero que pasa range()
? ¿No es eso un generador? En Python 3 es generador pero está envuelto en una clase que implementa los dos anteriores. Entoncesrange(100000)
lo , no ocupa mucha memoria, pero aún admite indexación e inversión eficientes.
En resumen, puede usar reversed(range(10))
sin ningún impacto en el rendimiento.
Creo que esto puede ayudar,
range(5)[::-1]
a continuación se muestra el uso:
for i in range(5)[::-1]:
print i
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed(range(10))
es menos propenso a errores. Sin ofender Asinox. Solo una observación honesta.
No necesariamente necesita usar la función de rango, simplemente puede hacer la lista [:: - 1] que debería devolver la lista en orden inverso rápidamente, sin usar ninguna adición.
Supongamos que tiene una lista, llámela a = {1,2,3,4,5}. Ahora, si desea imprimir la lista al revés, simplemente use el siguiente código.
a.reverse
for i in a:
print(i)
Sé que preguntaste usando el rango pero ya respondió.
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Es la forma correcta Si utiliza
reversed(range(10))
no obtendrás un caso 0. Por ejemplo, supongamos que su 10 no es un número mágico y una variable que está utilizando para buscar comenzar desde el reverso. Si su n caso es 0, invertido (rango (0)) no se ejecutará, lo cual es incorrecto si por casualidad tiene un solo objeto en el índice cero.
Pensé que muchos (como yo) podrían estar más interesados en un caso común de atravesar una lista existente en orden inverso , como se indica en el título, en lugar de solo generar índices para tal recorrido.
Aunque todas las respuestas correctas están perfectamente bien para este caso, quiero señalar que la comparación de rendimiento realizada en la respuesta de Wolf es solo para generar índices. Así que hice un punto de referencia similar para atravesar una lista existente en orden inverso.
TL; DR a[::-1]
es el más rápido.
Prerrequisitos:
a = list(range(10))
%timeit [a[9-i] for i in range(10)]
1.27 µs ± 61.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit a[::-1]
135 ns ± 4.07 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
La respuesta de Michał Šrajer :
%timeit list(reversed(a))
374 ns ± 9.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit [a[i] for i in range(9, -1, -1)]
1.09 µs ± 11.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Como puede ver, en este caso no hay necesidad de generar explícitamente índices, por lo que el método más rápido es el que realiza menos acciones adicionales.
NB: Probé en JupyterLab que tiene un práctico "comando mágico" %timeit
. Utiliza estándar timeit.timeit
debajo del capó. Probado para Python 3.7.3