number not loop from for python loops range python-2.x xrange

not - ¿Cuál es la diferencia entre las funciones de rango y rango en Python 2.X?



xrange is not defined (29)

Aparentemente, xrange es más rápido, pero no tengo ni idea de por qué es más rápido (y no hay pruebas aparte del anecdótico hasta el momento que sea más rápido) o qué es lo que, aparte de eso, es diferente

for i in range(0, 20): for i in xrange(0, 20):


el rango crea una lista, por lo que si lo hace el rango (1, 10000000) crea una lista en la memoria con 10000000 elementos. xrange es un generador, por lo que evalúa perezosamente.

Esto te trae dos ventajas:

  1. Puede iterar listas más largas sin obtener un MemoryError .
  2. A medida que se resuelve cada número perezosamente, si detiene la iteración anticipadamente, no perderá tiempo creando toda la lista.

el rango crea una lista, por lo que si realiza el range(1, 10000000) , crea una lista en la memoria con 9999999 elementos.

xrange es un generador, por lo que es una secuencia de objetos que se evalúa perezosamente.

Esto es cierto, pero en Python 3, .range() será implementado por Python 2 .xrange() . Si necesita generar la lista, deberá hacerlo:

list(range(1,100))


¡Recuerde, use el módulo timeit para probar cuál de los pequeños fragmentos de código es más rápido!

$ python -m timeit ''for i in range(1000000):'' '' pass'' 10 loops, best of 3: 90.5 msec per loop $ python -m timeit ''for i in xrange(1000000):'' '' pass'' 10 loops, best of 3: 51.1 msec per loop

Personalmente, siempre uso .range() , a menos que esté manejando listas realmente enormes, como se puede ver, en el tiempo, para una lista de un millón de entradas, la sobrecarga adicional es de solo 0.04 segundos. Y como señala Corey, en Python 3.0 .xrange() desaparecerá y .range() te dará un buen comportamiento de iterador de todos modos.


¿Qué?
range devuelve una lista estática en tiempo de ejecución.
xrange devuelve un object (que actúa como un generador, aunque ciertamente no lo es) a partir del cual los valores se generan cuando es necesario.

¿Cuándo usar cuál?

  • Use xrange si desea generar una lista para un rango gigantesco, digamos 1 billón, especialmente cuando tiene un "sistema sensible a la memoria" como un teléfono celular.
  • Utilice el range si desea iterar sobre la lista varias veces.

PS: Función de range Python 3.x == Función xrange Python 2.x.


Además, si do list(xrange(...)) será equivalente a range(...) .

Así que la list es lenta.

También xrange realmente no termina completamente la secuencia

Por eso no es una lista, es un objeto de xrange


Algunas de las otras respuestas mencionan que Python 3 eliminó el range de 2.x y renombró el range 2.x a range . Sin embargo, a menos que esté utilizando 3.0 o 3.1 (que nadie debería), en realidad es un tipo algo diferente.

Como dicen los documentos 3.1 :

Los objetos de rango tienen muy poco comportamiento: solo admiten la indexación, la iteración y la función len .

Sin embargo, en 3.2+, el range es una secuencia completa: admite segmentos extendidos y todos los métodos de collections.abc.Sequence con la misma semántica que una list . *

Y, al menos en CPython y PyPy (las únicas dos implementaciones 3.2+ que existen actualmente), también tiene implementaciones de tiempo constante de los métodos de index y count y del operador in (siempre y cuando solo pases los enteros). Esto significa que escribir 123456 in r es razonable en 3.2+, mientras que en 2.7 o 3.1 sería una idea horrible.

* El hecho de que issubclass(xrange, collections.Sequence) devuelva True en 2.6-2.7 y 3.0-3.1 es un error que se corrigió en 3.2 y no se realizó una copia de seguridad.


Cuando probé el rango contra xrange en un bucle (sé que debería usar timeit , pero esto fue hackeado rápidamente de la memoria usando un ejemplo de comprensión de lista simple) encontré lo siguiente:

import time for x in range(1, 10): t = time.time() [v*10 for v in range(1, 10000)] print "range: %.4f" % ((time.time()-t)*100) t = time.time() [v*10 for v in xrange(1, 10000)] print "xrange: %.4f" % ((time.time()-t)*100)

lo que da:

$python range_tests.py range: 0.4273 xrange: 0.3733 range: 0.3881 xrange: 0.3507 range: 0.3712 xrange: 0.3565 range: 0.4031 xrange: 0.3558 range: 0.3714 xrange: 0.3520 range: 0.3834 xrange: 0.3546 range: 0.3717 xrange: 0.3511 range: 0.3745 xrange: 0.3523 range: 0.3858 xrange: 0.3997 <- garbage collection?

O, usando xrange en el bucle for:

range: 0.4172 xrange: 0.3701 range: 0.3840 xrange: 0.3547 range: 0.3830 xrange: 0.3862 <- garbage collection? range: 0.4019 xrange: 0.3532 range: 0.3738 xrange: 0.3726 range: 0.3762 xrange: 0.3533 range: 0.3710 xrange: 0.3509 range: 0.3738 xrange: 0.3512 range: 0.3703 xrange: 0.3509

¿Mi prueba de fragmentos está correctamente? ¿Algún comentario sobre la instancia más lenta de xrange? O un mejor ejemplo :-)


De los documentos de ayuda.

Python 2.7.12

>>> print range.__doc__ range(stop) -> list of integers range(start, stop[, step]) -> list of integers Return a list containing an arithmetic progression of integers. range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0. When step is given, it specifies the increment (or decrement). For example, range(4) returns [0, 1, 2, 3]. The end point is omitted! These are exactly the valid indices for a list of 4 elements. >>> print xrange.__doc__ xrange(stop) -> xrange object xrange(start, stop[, step]) -> xrange object Like range(), but instead of returning a list, returns an object that generates the numbers in the range on demand. For looping, this is slightly faster than range() and more memory efficient.

Python 3.5.2

>>> print(range.__doc__) range(stop) -> range object range(start, stop[, step]) -> range object Return an object that produces a sequence of integers from start (inclusive) to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1. start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3. These are exactly the valid indices for a list of 4 elements. When step is given, it specifies the increment (or decrement). >>> print(xrange.__doc__) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name ''xrange'' is not defined

La diferencia es aparente. En Python 2.x, el range devuelve una lista, xrange devuelve un objeto xrange que es iterable.

En Python 3.x, el range convierte en xrange de Python 2.x, y xrange se elimina.


El rango genera la lista completa y la devuelve. xrange no lo hace: genera los números en la lista a pedido.


En python 2.x

range (x) devuelve una lista, que se crea en la memoria con x elementos.

>>> a = range(5) >>> a [0, 1, 2, 3, 4]

xrange (x) devuelve un objeto xrange que es un obj generador que genera los números a pedido. se calculan durante for-loop (Evaluación perezosa).

Para bucles, esto es ligeramente más rápido que el rango () y más eficiente en memoria.

>>> b = xrange(5) >>> b xrange(5)


En un requisito para escanear / imprimir elementos de 0-N, el rango y el rango de trabajo funcionan de la siguiente manera.

range (): crea una nueva lista en la memoria y toma el total de 0 a N elementos (totalmente N + 1) y los imprime. xrange (): crea una instancia de iterador que escanea a través de los elementos y mantiene solo el elemento encontrado actual en la memoria, por lo tanto, utiliza la misma cantidad de memoria todo el tiempo.

En caso de que el elemento requerido sea solo algo al principio de la lista, entonces ahorra una buena cantidad de tiempo y memoria.


Encontrará la ventaja de xrange sobre el range en este sencillo ejemplo:

import timeit t1 = timeit.default_timer() a = 0 for i in xrange(1, 100000000): pass t2 = timeit.default_timer() print "time taken: ", (t2-t1) # 4.49153590202 seconds t1 = timeit.default_timer() a = 0 for i in range(1, 100000000): pass t2 = timeit.default_timer() print "time taken: ", (t2-t1) # 7.04547905922 seconds

El ejemplo anterior no refleja nada sustancialmente mejor en caso de xrange .

Ahora observe el siguiente caso en el que el range es realmente lento, comparado con xrange .

import timeit t1 = timeit.default_timer() a = 0 for i in xrange(1, 100000000): if i == 10000: break t2 = timeit.default_timer() print "time taken: ", (t2-t1) # 0.000764846801758 seconds t1 = timeit.default_timer() a = 0 for i in range(1, 100000000): if i == 10000: break t2 = timeit.default_timer() print "time taken: ", (t2-t1) # 2.78506207466 seconds

Con el range , ya crea una lista de 0 a 100000000 (requiere mucho tiempo), pero xrange es un generador y solo genera números según la necesidad, es decir, si la iteración continúa.

En Python-3, la implementación de la funcionalidad de range es la misma que la de xrange en Python-2, mientras que eliminaron xrange en Python-3

Feliz codificacion !!


Es por razones de optimización.

range () creará una lista de valores de principio a fin (0 .. 20 en su ejemplo). Esto se convertirá en una operación costosa en rangos muy grandes.

xrange () por otro lado está mucho más optimizado. solo calculará el siguiente valor cuando sea necesario (a través de un objeto de secuencia xrange) y no crea una lista de todos los valores, como lo hace el rango ().


Estoy sorprendido de que nadie lea el doc :

Esta función es muy similar a range() , pero devuelve un objeto xrange lugar de una lista. Este es un tipo de secuencia opaca que produce los mismos valores que la lista correspondiente, sin realmente almacenarlos todos simultáneamente. La ventaja de xrange() sobre el range() es mínima (ya que xrange() aún tiene que crear los valores cuando se lo piden), excepto cuando se utiliza un rango muy grande en una máquina con falta de memoria o cuando todos los elementos del rango son nunca se utiliza (como cuando el bucle normalmente termina con break ).


La diferencia disminuye para que los argumentos más pequeños xrange(..) / xrange(..) :

$ python -m timeit "for i in xrange(10111):" " for k in range(100):" " pass" 10 loops, best of 3: 59.4 msec per loop $ python -m timeit "for i in xrange(10111):" " for k in xrange(100):" " pass" 10 loops, best of 3: 46.9 msec per loop

En este caso, xrange(100) es solo un 20% más eficiente.



Mira esta post para encontrar la diferencia entre rango y rango:

Citar:

range devuelve exactamente lo que piensas: una lista de enteros consecutivos, de una longitud definida que comienza con 0. xrange , sin embargo, devuelve un "objeto de rango" , que actúa como un iterador


Pasa algún tiempo con la Biblioteca de Referencia . Cuanto más familiarizado esté con él, más rápido podrá encontrar respuestas a preguntas como esta. Especialmente importantes son los primeros capítulos sobre objetos y tipos incorporados.

La ventaja del tipo xrange es que un objeto xrange siempre tomará la misma cantidad de memoria, sin importar el tamaño del rango que represente. No hay ventajas de rendimiento consistentes.

Otra forma de encontrar información rápida sobre una construcción Python es la cadena de documentación y la función de ayuda:

print xrange.__doc__ # def doc(x): print x.__doc__ is super useful help(xrange)


Todo el mundo lo ha explicado mucho. Pero quería que lo viera por mí mismo. Yo uso python3. Entonces, abrí el monitor de recursos (en Windows!), Y primero, ejecuté el siguiente comando primero:

a=0 for i in range(1,100000): a=a+i

y luego verificó el cambio en la memoria ''En uso''. Fue insignificante. Entonces, corrí el siguiente código:

for i in list(range(1,100000)): a=a+i

Y tomó una gran parte de la memoria para su uso, al instante. Y, estaba convencido. Puedes probarlo por ti mismo.

Si está utilizando Python 2X, reemplace ''range ()'' con ''xrange ()'' en el primer código y ''list (range ())'' con ''range ()''.


el rango crea una lista, por lo que si realiza el range(1, 10000000) , crea una lista en la memoria con 9999999 elementos.

xrange es un objeto de secuencia que se evalúa perezosamente.

Se debe agregar de la sugerencia de @ Thiago, que en python3, el rango hace el equivalente de xrange de python


rango: el rango llenará todo de una vez, lo que significa que cada número del rango ocupará la memoria.

xrange: -xrange es algo así como un generador, aparecerá en la imagen cuando desee el rango de números pero no desea que se almacenen, como cuando quiere usar la memoria de loop.so.


xrange () y range () en python funcionan de manera similar a la del usuario, pero la diferencia se produce cuando estamos hablando de cómo se asigna la memoria al usar ambas funciones.

Cuando usamos el rango (), asignamos memoria para todas las variables que está generando, por lo que no se recomienda usar con un no mayor. de variables a generar.

Por otro lado, xrange () genera solo un valor particular a la vez y solo se puede usar con el bucle for para imprimir todos los valores requeridos.


xrange devuelve un iterador y solo mantiene un número en la memoria a la vez. El rango mantiene la lista completa de números en la memoria.


xrange utiliza un iterador (genera valores sobre la marcha), el rango devuelve una lista.


range(x,y) devuelve una lista de cada número entre xey y si usa un bucle for , entonces el range es más lento. De hecho, el range tiene un rango de índice más grande. range(xy) imprimirá una lista de todos los números entre x e y

xrange(x,y) devuelve xrange(x,y) pero si usó un bucle for , entonces xrange es más rápido. xrange tiene un rango de índice más pequeño. xrange no solo imprimirá xrange(x,y) sino que mantendrá todos los números que hay en ella.

[In] range(1,10) [Out] [1, 2, 3, 4, 5, 6, 7, 8, 9] [In] xrange(1,10) [Out] xrange(1,10)

Si utiliza un bucle for , entonces funcionaría

[In] for i in range(1,10): print i [Out] 1 2 3 4 5 6 7 8 9 [In] for i in xrange(1,10): print i [Out] 1 2 3 4 5 6 7 8 9

No hay mucha diferencia cuando se usan bucles, ¡aunque hay una diferencia cuando solo se imprime!


xrange solo almacena los parámetros de rango y genera los números a pedido. Sin embargo, la implementación en C de Python actualmente restringe sus argumentos a largos en C:

xrange(2**32-1, 2**32+1) # When long is 32 bits, OverflowError: Python int too large to convert to C long range(2**32-1, 2**32+1) # OK --> [4294967295L, 4294967296L]

Tenga en cuenta que en Python 3.0 solo hay range y se comporta como el xrange 2.x pero sin las limitaciones de los puntos finales mínimos y máximos.


Range devuelve una lista, mientras que xrange devuelve un objeto xrange que toma la misma memoria independientemente del tamaño del rango, ya que en este caso, solo se genera un elemento y está disponible por iteración, mientras que en el caso de usar range, todos los elementos se generan a la vez y Están disponibles en la memoria.


range () vs xrange () en python:

range () y xrange () son dos funciones que se pueden usar para iterar un cierto número de veces en los bucles de Python. En Python 3, no hay xrange, pero la función de rango se comporta como xrange en Python 2. Si desea escribir código que se ejecute tanto en Python 2 como en Python 3, debe usar range ().

range () - Esto devuelve una lista de números creados usando la función range ().

xrange (): esta función devuelve el objeto generador que se puede usar para mostrar números solo en bucle. Solo el rango particular se muestra a pedido y, por lo tanto, se llama "evaluación perezosa".

Ambos se implementan de diferentes maneras y tienen diferentes características asociadas a ellos. Los puntos de comparaciones son:

  1. Tipo de retorno Memoria Operación Velocidad de uso
  2. Memoria
  3. Uso de la operación
  4. Velocidad

1. Tipo de devolución:

range () devuelve - la lista como tipo de retorno.

xrange () devuelve - objeto xrange ().

# initializing a with range() a = range(1,10000) # initializing a with xrange() x = xrange(1,10000) # testing the type of a print ("The return type of range() is : ") print (type(a)) # testing the type of x print ("The return type of xrange() is : ") print (type(x))

Salida:

The return type of range() is : <type ''list''> The return type of xrange() is : <type ''xrange''>

2. Memoria:

La variable que almacena el rango creado por range () toma más memoria en comparación con la variable que almacena el rango usando xrange (). La razón básica de esto es que el tipo de retorno de range () es list y xrange () es un objeto xrange ().

# initializing a with range() a = range(1,10000) # initializing a with xrange() x = xrange(1,10000) # testing the size of a print ("The size allotted using range() is : ") print (sys.getsizeof(a)) # testing the size of a print ("The size allotted using xrange() is : ") print (sys.getsizeof(x))

Salida:

The size allotted using range() is : 80064 The size allotted using xrange() is : 40

3. Uso de operaciones:

Como range () devuelve la lista, todas las operaciones que se pueden aplicar en la lista se pueden usar en ella. Por otro lado, como xrange () devuelve el objeto xrange, las operaciones asociadas a la lista no se pueden aplicar a ellos, por lo tanto, es una desventaja.

# Python code to demonstrate range() vs xrange() # on basis of operations usage # initializing a with range() a = range(1,6) # initializing a with xrange() x = xrange(1,6) # testing usage of slice operation on range() print ("The list after slicing using range is : ") print (a[2:5]) # testing usage of slice operation on xrange() print ("The list after slicing using xrange is : ") print (x[2:5])

Salida:

The list after slicing using range is : [3, 4, 5] The list after slicing using xrange is : Traceback (most recent call last): File "pp.py", line 18, in <module> print (x[2:5]) TypeError: sequence index must be integer, not ''slice''

4. Velocidad:

Debido al hecho de que xrange () evalúa solo el objeto generador que contiene solo los valores requeridos por la evaluación perezosa, por lo tanto, es más rápido en la implementación que en range ().

Puntos importantes :

  1. Si desea escribir código que se ejecute tanto en Python 2 como en Python 3, use range () ya que la función xrange está obsoleta en Python 3.
  2. El rango () es más rápido si se itera sobre la misma secuencia varias veces.
  3. xrange () tiene que reconstruir el objeto entero cada vez, pero el rango () tendrá objetos enteros reales. (Sin embargo, siempre se desempeñará peor en términos de memoria).

Reference


range (): range (1, 10) devuelve una lista de 1 a 10 números y mantiene la lista completa en la memoria.

xrange (): como range (), pero en lugar de devolver una lista, devuelve un objeto que genera los números en el rango a pedido. Para bucles, esto es ligeramente más rápido que el rango () y más eficiente en memoria. xrange () se opone a un iterador y genera los números a pedido. (Evaluación perezosa)

In [1]: range(1,10) Out[1]: [1, 2, 3, 4, 5, 6, 7, 8, 9] In [2]: xrange(10) Out[2]: xrange(10) In [3]: print xrange.__doc__ xrange([start,] stop[, step]) -> xrange object