Imprime una lista en orden inverso con range ()?

364

¿Cómo se puede producir la siguiente lista range()en Python?

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
ramesh.mimit
fuente
¿Qué pasa con [* rango (9, -1, -1)]? Súper pitón!
onofricamila

Respuestas:

561

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 rangepara 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.

Michał Šrajer
fuente
13
Aunque "es" menos eficiente. Y no puedes hacer operaciones de corte en él.
Jakob Bowyer
66
Esta respuesta es muy clara y fácil de entender, pero debe serlo range(10), no range(9). Además, si desea una lista completa (para cortar, etc.), debe hacerlo list(reversed(range(10))).
John Y
55
Esto produce un iterador, OP solicitó un resultado en forma de una lista.
btk
66
El uso de "invertido" con el generador de Python (suponiendo que estemos hablando del rango incorporado de Python 3) es conceptualmente incorrecto y enseña hábitos incorrectos de no considerar la complejidad de la memoria / procesamiento cuando se programa en lenguaje de alto nivel.
thedk
77
En Python3, reversedno acepta generadores en general, pero acepta range. ¿Por qué reversed(range(10000))necesitaría asignar memoria para toda la lista? rangepuede devolver un objeto que implementa el __reversed__método que permite una iteración inversa eficiente?
avmohan
312

Use la función incorporada 'rango'. La firma es range(start, stop, step). Esto produce una secuencia que produce números, comenzando starty terminando si stopse 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 rangeobjeto que no es una lista , que funciona efectivamente como una lista de solo lectura (pero usa mucha menos memoria, particularmente para grandes rangos).

Señor b
fuente
1
¿Puede explicar esto también, también puede recomendarme cualquier sitio web / libro en pdf para python
Ramesh.mimit
8
@ramesh Si ejecuta 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)
Michael Mrozek
3
@ ramesh.mimit: solo ve al sitio oficial de Python. Hay documentación completa allí, incluido un gran tutorial.
John Y
55
Realmente, esta es la respuesta adecuada, pero podría explicarse más claramente. range(start, stop, step) - comience en el número starty produzca resultados a menos que stopse haya alcanzado, moviéndose stepcada vez.
Sr. B
43

Podría usar range(10)[::-1]cuál es lo mismo range(9, -1, -1)y posiblemente más legible (si está familiarizado con el sequence[::-1]idioma común de Python).

Martineau
fuente
28

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 .

Lobo
fuente
3
Hice mis propios tiempos antes de leer esta respuesta, y obtuve los mismos resultados.
Todd Owen
13
for i in range(8, 0, -1)

Resolverá este problema. Producirá 8 a 1, y -1 significa una lista invertida

Jutta
fuente
10

No tiene sentido usarlo reverseporque 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 stepy establecerlo -1, otros parámetros se ajustarán en consecuencia:

  1. Proporcione el parámetro de parada como -1(su valor anterior de stop - 1, stopera igual a 0).
  2. Como parámetro de inicio uso 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]
Andriy Ivaneyko
fuente
66
Francamente, esto me parece menos intuitivo quereversed(range(n))
Nicholas Hamilton
1
@NicholasHamilton De acuerdo con usted, sin embargo, la idea detrás de esa respuesta es usar menos recursos ... (y la pregunta era sobre usar solo la función de rango :))
Andriy Ivaneyko
Ok, no te preocupes, supongo que depende de la situación. Por ejemplo, si la función de rango se usa como índice para un bucle, tendrá un efecto limitado, sin embargo, si se usa dentro de un bucle externo, el costo se agravará ...
Nicholas Hamilton
8

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 :)

Jaime RGP
fuente
es bueno tener algunos números :) - ¿por qué no agregaste range(1000000000-1,-1,-1)también?
Wolf
... mejor no lo intentes timeit range(1000000000-1,-1,-1)en la línea de comando, en cambio ve mis resultados :-)
Wolf
6

El requisito en esta pregunta requiere un número listentero 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]
un33k
fuente
2
Realmente me gusta el triple.-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.
lobo
5

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

Sr. Suryaa Jha
fuente
5

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 ():

  1. Ya sea soporte len()e índices enteros a través de[]
  2. O tener un __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.

Shital Shah
fuente
3

Creo que esto puede ayudar,

range(5)[::-1]

a continuación se muestra el uso:

for i in range(5)[::-1]:
    print i 
dineshsprabu
fuente
3
range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Asinox
fuente
13
Su respuesta muestra por qué reversed(range(10))es menos propenso a errores. Sin ofender Asinox. Solo una observación honesta.
Michał Šrajer
No sé si es estándar dejar en la pantalla respuestas erróneas. ¿Puedo yo o alguien corregirlo o incluso eliminarlo?
sinekonata
3
@sine, no, solo déjalo y pregúntate cómo acumuló 3 votos a favor ... Supongo que podrías marcarlo para la atención del moderador (duplicado de la respuesta de 18 meses antes, excepto roto), no estoy seguro de si lo eliminarían o no.
OGHaza
Para toda referencia futura: el código solo no es VLQ , y tampoco se supone que las respuestas incorrectas estén marcadas . Vota a favor y sigue adelante, pero la marcación es incorrecta en este caso, ya sea NAA o marca de mod. - De la revisión
Zoe
2

Utilizando sin [:: - 1] o invertido -

def reverse(text):
    result = []
    for index in range(len(text)-1,-1,-1):
        c = text[index]
        result.append(c)
    return ''.join(result)

print reverse("python!")
rhel.user
fuente
66
¿Por qué alguien debería escribir esto en lugar de "python!"[::-1]?
Daniel
1
[9-i for i in range(10)]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Jason
fuente
1

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.

usuario7420740
fuente
Esta parece ser la solución sugerida en una respuesta anterior . También parece que podrías estar tratando de comentar una respuesta anterior diferente; necesitarás tener un poco más de reputación antes de poder hacerlo.
Grisha Levit
1

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ó.

Vishal Kumar
fuente
0
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.

usuario3807372
fuente
0

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))

La respuesta de Jason :

%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)

La respuesta de martineau :

%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)

La respuesta de bene :

%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.timeitdebajo del capó. Probado para Python 3.7.3

pkuderov
fuente