Question Quelle est la différence entre les fonctions range et xrange dans Python 2.X?


Apparemment, xrange est plus rapide mais je ne sais pas pourquoi c'est plus rapide (et pas de preuve en dehors de l'anecdotique jusqu'à présent, c'est plus rapide) ou quoi d'autre est différent

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

613
2017-09-18 17:52


origine


Réponses:


range crée une liste, donc si vous faites range(1, 10000000) il crée une liste en mémoire avec 9999999 éléments.

xrange est un objet de séquence qui évalue paresseusement.

Il devrait être ajouté à partir de l'indice @ Thiago, que dans python3, range fait l'équivalent de xrange de python


702
2017-09-18 17:55



range crée une liste, donc si vous faites range(1, 10000000) il crée une liste en mémoire avec 9999999 éléments.

xrange  est un générateur, donc est un objet de séquence est un cela évalue paresseusement.

C'est vrai, mais dans Python 3, la plage sera implémentée par le Python 2 xrange (). Si vous devez réellement générer la liste, vous devrez faire:

list(range(1,100))

210
2017-09-18 18:08



Rappelez-vous, utilisez le module timeit pour tester lequel des petits morceaux de code est plus rapide!

$ 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

Personnellement, j'utilise toujours range (), sauf si je faisais affaire avec vraiment énormes listes - comme vous pouvez le voir, dans le temps, pour une liste d'un million d'entrées, le surcoût supplémentaire est seulement de 0,04 secondes. Et comme Corey le fait remarquer, dans Python 3.0, xrange disparaîtra et range vous donnera un bon comportement d'itérateur de toute façon.


99
2017-09-18 22:11



xrange stocke uniquement les paramètres de plage et génère les numéros à la demande. Cependant l'implémentation C de Python limite actuellement ses args aux longs 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]

Notez que dans Python 3.0 il n'y a que range et il se comporte comme le 2.x xrange mais sans les limitations sur les points finaux minimum et maximum.


64
2017-09-18 18:13



xrange renvoie un itérateur et ne garde qu'un seul numéro en mémoire à la fois. range garde la liste entière des nombres en mémoire.


36
2017-09-18 17:55



Passez du temps avec Référence de la bibliothèque. Plus vous êtes familier avec cela, plus vite vous pouvez trouver des réponses à des questions comme celle-ci. Les premiers chapitres sur les objets et les types intégrés sont particulièrement importants.

L'avantage du type xrange est qu'un objet xrange sera toujours   prendre la même quantité de mémoire, peu importe la taille de la gamme qu'il représente.   Il n'y a pas d'avantages de performance constants.

Une autre façon de trouver des informations rapides sur une construction Python est la docstring et la fonction d'aide:

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

28
2017-09-18 17:55



range () vs xrange () en python:

range () et xrange () sont deux fonctions qui pourraient être utilisées pour répéter un certain nombre de fois les boucles en Python. En Python 3, il n'y a pas de xrange, mais la fonction range se comporte comme xrange dans Python 2. Si vous voulez écrire du code qui s'exécutera sur Python 2 et Python 3, vous devez utiliser range ().

gamme() - Cela retourne une liste de nombres créés en utilisant la fonction range ().

xrange () - Cette fonction renvoie l'objet générateur qui peut être utilisé pour afficher les nombres uniquement en boucle. Seule une plage particulière est affichée à la demande et donc appelée "évaluation paresseuse".

Les deux sont mis en œuvre de différentes manières et ont des caractéristiques différentes qui leur sont associées. Les points de comparaison sont:

  1. Type de retour Fonctionnement de la mémoire Vitesse d'utilisation
  2. Mémoire
  3. Opération Utilisation
  4. La vitesse

1. Type de retour:

range () renvoie - la liste en tant que type de retour.

xrange () renvoie - Objet 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))

Sortie:

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

2. Mémoire:

La variable stockant la plage créée par range () prend plus de mémoire par rapport à la variable qui stocke la plage en utilisant xrange (). La raison fondamentale de ceci est le type de retour de range () est list et xrange () est l'objet 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))

Sortie:

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

3. Utilisation des opérations:

Comme range () renvoie la liste, toutes les opérations qui peuvent être appliquées sur la liste peuvent être utilisées. D'un autre côté, lorsque xrange () renvoie l'objet xrange, les opérations associées à la liste ne peuvent pas être appliquées, donc un inconvénient.

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

Sortie: 

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. Vitesse:

Du fait que xrange () n'évalue que l'objet générateur contenant uniquement les valeurs requises par l'évaluation paresseuse, il est donc plus rapide dans l'implémentation que range ().

Les points importants :

  1. Si vous voulez écrire du code qui fonctionnera sur Python 2 et Python 3, utilisez range () car la fonction xrange est déconseillée dans Python 3.
  2. range () est plus rapide si itérant sur la même séquence multiple fois.
  3. xrange () doit reconstruire l'objet entier à chaque fois, mais range () aura des objets entiers réels. (Il va toujours effectuer pire en termes de mémoire cependant).

Référence 


15
2017-11-05 07:02



range crée une liste, donc si vous rangez (1, 10000000) il crée une liste en mémoire avec 10000000 éléments.   xrange est un générateur, donc il évalue paresseusement.

Cela vous apporte deux avantages:

  1. Vous pouvez itérer des listes plus longues sans avoir MemoryError.
  2. Comme il résout chaque numéro paresseusement, si vous arrêtez l'itération tôt, vous ne perdrez pas de temps à créer toute la liste.

12
2017-09-18 18:44



Je suis choqué, personne n'a lu doc:

Cette fonction est très similaire à range(), mais retourne un xrange objet au lieu d'une liste. C'est un type de séquence opaque qui donne les mêmes valeurs que la liste correspondante, sans les stocker toutes simultanément. L'avantage de xrange() plus de range() est minime (depuis xrange() doit toujours créer les valeurs lorsqu'on lui en demande), sauf lorsqu'une très grande plage est utilisée sur une machine privée de mémoire ou lorsque tous les éléments de la plage ne sont jamais utilisés (comme lorsque la boucle est généralement terminée avec break).


12
2018-04-07 06:25



C'est pour des raisons d'optimisation.

range () créera une liste de valeurs du début à la fin (0 .. 20 dans votre exemple). Cela deviendra une opération coûteuse sur de très grandes plages.

D'autre part, xrange () est beaucoup plus optimisé. il ne calcule la valeur suivante que lorsque cela est nécessaire (via un objet de séquence xrange) et ne crée pas une liste de toutes les valeurs comme range ().


10
2017-09-18 17:59



Vous trouverez l'avantage de xrange plus de range dans cet exemple simple:

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

L'exemple ci-dessus ne reflète absolument rien de mieux en cas de xrange.

Maintenant, regardez le cas suivant où rangeest vraiment très lent, comparé à 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

Avec range, il crée déjà une liste de 0 à 100000000 (temps), mais xrange est un générateur et génère uniquement des nombres basés sur le besoin, c'est-à-dire si l'itération continue.

En Python-3, la mise en œuvre du range la fonctionnalité est la même que celle de xrange dans Python-2, alors qu'ils ont fait disparaître xrange en Python-3

Codage heureux !!


10
2017-10-22 11:34