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

apparemment xrange est plus rapide, mais je n'ai aucune idée de pourquoi il est plus rapide (et aucune preuve à part l'anecdote jusqu'à présent qu'il est plus rapide) ou ce qui en outre est différent sur

for i in range(0, 20):
for i in xrange(0, 20):
620
demandé sur kmario23 2008-09-18 21:52:51

28 réponses

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

xrange est un objet séquentiel qui est évalué paresseusement.

il faut ajouter à partir de l'indice de @Thiago, que dans python3, range fait l'équivalent de xrange de python

711
répondu Charles 2018-04-16 10:31:05

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

xrange est un générateur, de sorte qu'il est un objet séquence est un qui évalue paresseusement.

c'est vrai, mais en Python 3, range sera implémenté par xrange(). Si vous avez besoin de réellement générer la liste, vous aurez besoin de faire:

list(range(1,100))
212
répondu Corey 2017-10-27 05:22:56

rappelez-vous, utilisez le module timeit pour tester lequel des petits snipps de code est le 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 m'occupais de vraiment listes énormes -- comme vous pouvez le voir, le temps-sage, pour une liste d'un million d'entrées, les frais généraux supplémentaires est seulement 0.04 secondes. Et comme Corey le souligne, en Python 3.0 xrange disparaîtra et range vous donnera de toute façon un comportement itérateur agréable.

99
répondu John Fouhy 2008-09-18 22:11:15

xrange stocke seulement les params de gamme et génère les nombres sur demande. Cependant L'implémentation C de Python limite actuellement son args à C longs:

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 qu'en Python 3.0 il n'y a que range et il se comporte comme le 2.x xrange , mais sans les limites relatives aux points limites minimal et maximal.

64
répondu efotinis 2015-10-16 15:33:04

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

37
répondu Ben Hoffstein 2008-09-18 17:55:00

Faire passer un peu de temps avec le Librairie de Référence . Plus vous êtes familiarisé avec elle, plus vite vous pouvez trouver des réponses à des questions comme celle-ci. Les premiers chapitres sur les objets et les types de construction 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 plage qu'elle représente. Il n'y a pas des performances constantes avantage.

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

print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
28
répondu Antti Rasinen 2008-09-18 18:55:17

range () vs xrange () in python :

range() et xrange () sont deux fonctions qui peuvent être utilisées pour itérer un certain nombre de fois dans les boucles en Python. En Python 3 , Il n'y a pas de xrange, mais la fonction range se comporte comme xrange en Python 2.Si vous voulez écrire du code qui fonctionnera à la fois sur Python 2 et Python 3, vous devez utiliser range().

range() – Cela renvoie une liste de numéros de créé à l'aide de gamme() fonction.

xrange () – cette fonction renvoie l'objet générateur qui peut être utilisé pour afficher des nombres uniquement par boucle. Seule une gamme particulière est affichée sur demande et donc appelée "évaluation paresseuse".

les deux sont mis en œuvre de différentes façons et ont des caractéristiques différentes associées à eux. Les points de comparaison sont:

  1. Type De Retour De Fonctionnement De La Mémoire Vitesse D'Utilisation
  2. Mémoire
  3. Utilisation Opérationnelle
  4. vitesse

1. Type De Retour:

range() renvoie la liste comme type de retour.

xrange() renvoie xrange() de l'objet.

# 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 que la variable stockant la plage en utilisant xrange(). La raison principale est le type de retour de l'objet range() est list et xrange() est 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:

Que range() retourne la liste de toutes les opérations qui peuvent être appliquées sur la liste peuvent être utilisés. D'autre part, comme xrange() renvoie l'objet xrange, les opérations associées à list ne peuvent pas être appliquées sur eux, 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:

en raison du fait que xrange () n'évalue que l'objet générateur contenant seulement les valeurs qui sont exigées par lazy evaluation, est donc plus rapide dans la mise en œuvre que range().

Points Importants:

  1. si vous voulez écrire du code qui fonctionnera à la fois sur Python 2 et Python 3, Utilisez la plage () car la fonction xrange est dépréciée en Python 3.
  2. range () est plus rapide si l'itération sur la même séquence multiple temps.
  3. xrange() doit reconstruire l'objet entier à chaque fois, mais range () aura de vrais objets integer. (Il sera toujours effectuer le pire en termes de mémoire).

référence

17
répondu Chirag Maliwal 2018-09-21 13:04:23

gamme crée une liste, donc si vous ne range(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 obtenir un MemoryError .
  2. comme il résout chaque nombre paresseusement, si vous arrêtez itération tôt, vous ne perdrez pas de temps à créer la liste entière.
12
répondu Lucas S. 2015-10-16 15:35:03

je suis choqué personne ne lit doc :

cette fonction est très similaire à range() , mais renvoie un objet xrange au lieu d'une liste. Il s'agit d'un type de séquence opaque qui fournit les mêmes valeurs que la liste correspondante, sans les stocker en même temps. L'avantage de xrange() sur range() est minime (puisque xrange() doit encore créer les valeurs lorsqu'on les demande) sauf lorsqu'une très grande portée est utilisée sur une machine privée de mémoire ou lorsque tous les éléments de la gamme ne sont jamais utilisés (comme lorsque la boucle est habituellement terminée avec break ).

12
répondu Kishor Pawar 2016-11-09 18:14:46

C'est pour des raisons d'optimisation.

range () va créer 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 portées.

xrange () en revanche est beaucoup plus optimisé. il ne calcule la valeur suivante qu'en cas de besoin (via un objet xrange sequence) et ne crée pas de liste de toutes les valeurs comme range() does.

10
répondu QAZ 2008-09-18 17:59:46

vous trouverez l'avantage de xrange sur range dans ce simple exemple:

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 rien de bien meilleur dans le cas de xrange .

regardez maintenant le cas suivant où range est 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 (longue), mais xrange est un générateur et ne génère des nombres basés que sur le besoin, c'est-à-dire si l'itération continue.

en Python-3, l'implémentation de la fonctionnalité range est la même que celle de xrange en Python-2, alors qu'ils ont supprimé xrange en Python-3

Bon Codage!!

10
répondu User_Targaryen 2016-10-22 13:30:59

range (): range(1, 10) retourne une liste de 1 à 10 nombres et conserve la liste entière en mémoire.

xrange (): comme range(), mais au lieu de retourner une liste, retourne un objet qui génère les nombres dans la gamme à la demande. Pour la boucle, c'est légèrement plus rapide que range() et plus efficace en mémoire. xrange () produit les nombres sur demande.(Lazy Evaluation)

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
8
répondu Tushar.PUCSD 2016-03-20 07:45:06

range(x,y) retourne une liste de chaque nombre entre x et y si vous utilisez une boucle for , alors range est plus lent. En fait, range a une plus grande fourchette D'indices. range(x.y) va imprimer une liste de tous les numéros entre x et y

xrange(x,y) retourne xrange(x,y) mais si vous avez utilisé une boucle for , alors xrange est plus rapide. xrange a une plus petite fourchette D'indices. xrange n'imprimera pas seulement xrange(x,y) mais il conservera tous les numéros qu'il contient.

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

si vous utilisez une boucle for , alors elle fonctionnerait

[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

il n'y a pas beaucoup de différence lors de l'utilisation des boucles, bien qu'il y ait une différence lors de l'impression!

7
répondu Supercolbat 2016-11-29 01:37:20

en python 2.x

range(x) retourne une liste, qui est créée en mémoire avec des éléments X.

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

xrange(x) renvoie un objet xrange qui est un générateur obj qui génère les nombres à la demande. ils sont calculés au cours de la boucle(Lazy Evaluation).

pour la boucle, c'est un peu plus rapide que la portée() et plus efficace en mémoire.

>>> b = xrange(5)
>>> b
xrange(5)
6
répondu SrmHitter9062 2016-02-28 09:42:31

lors des essais de portée contre xrange dans une boucle (je sais que je devrais utiliser timeit , mais cela a été rapidement hacké de mémoire en utilisant un exemple simple de compréhension de liste) j'ai trouvé ce qui suit:

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)

qui donne:

$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?

Ou, à l'aide de xrange dans la boucle 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

est-ce que mes tests sont corrects? Des commentaires sur l'instance plus lente de xrange? Ou un meilleur exemple :-)

5
répondu Dave Everitt 2011-03-18 12:04:59

certaines des autres réponses mentionnent que Python 3 a éliminé 2.x's range et renommé 2.x xrange à range . Cependant, à moins que vous utilisiez 3.0 ou 3.1 (ce que personne ne devrait être), c'est en fait un type quelque peu différent.

Comme l'3.1 docs dis:

Les objets de portée

ont très peu de comportement: ils ne supportent que l'indexation, l'itération et la fonction len .

Cependant, en 3.2+, range est une séquence complète-il soutient tranches étendues, et toutes les méthodes de collections.abc.Sequence avec la même sémantique que list . *

et, au moins dans CPython et PyPy (les deux seules implémentations de 3.2+ qui existent actuellement), il a aussi des implémentations à temps constant des méthodes index et count et les in ." opérateur (aussi longtemps que vous le passer entiers). Cela signifie qu'écrire 123456 in r est raisonnable en 3.2+, alors qu'en 2.7 ou 3.1 ce serait une idée horrible.


* le fait que issubclass(xrange, collections.Sequence) renvoie True en 2.6-2.7 et 3.0-3.1 est un bug qui a été corrigé en 3.2 et non rétroporté.

5
répondu abarnert 2015-05-06 21:57:10

xrange() et range () en python fonctionnent de la même manière que pour l'utilisateur , mais la différence vient quand nous parlons de la façon dont la mémoire est allouée en utilisant à la fois la fonction.

lorsque nous utilisons range() nous affectons la mémoire pour toutes les variables qu'elle génère, il n'est donc pas recommandé d'utiliser avec plus grand no. de variables qui doivent être générés.

xrange() en revanche ne génère qu'une valeur particulière à un moment donné et ne peut être utilisé qu'avec la boucle for pour imprimer toutes les valeurs requises.

4
répondu Lakshaya Maheshwari 2016-01-19 12:48:45

range génère la liste entière et la renvoie. xrange ne produit pas -- il génère les nombres dans la liste à la demande.

3
répondu Eddie Deyo 2008-09-18 17:55:27

lire le post suivant pour la comparaison entre la gamme et xrange avec analyse graphique.

Python range Vs xrange

3
répondu Harsha Vardhan 2015-08-01 11:37:56

xrange utilise un itérateur (génère des valeurs à la volée), range renvoie une liste.

2
répondu hacama 2008-09-18 17:55:30

quoi?

range renvoie une liste statique à l'exécution.

xrange retourne un object (qui agit comme un générateur, bien qu'il ne soit certainement pas un) à partir duquel les valeurs sont générées comme et quand requis.

quand utiliser lequel?

  • utilisez xrange si vous voulez générer une liste pour une gamme gigantesque, disons 1 milliard, surtout quand vous avez une " mémoire sensible système" comme un téléphone cellulaire.
  • utilisez range si vous voulez itérer sur la liste plusieurs fois.

PS: Python 3.la fonction range de x == Python 2.la fonction xrange de x.

2
répondu kmario23 2015-05-06 23:06:19

sur une exigence de numérisation/impression d'articles 0-N , gamme et xrange fonctionne comme suit.

range () - crée une nouvelle liste dans la mémoire et prend l'ensemble des éléments 0 à N (totalement N+1) et les imprime. xrange () - crée une instance itératrice qui scanne les éléments et garde seulement l'élément rencontré en cours dans la mémoire , utilisant ainsi la même quantité de mémoire tout le temps.

dans le cas où l'élément requis est quelque peu à la début de la liste seulement alors il sauve une bonne quantité de temps et de mémoire.

1
répondu SomeDoubts 2014-01-15 12:45:29

la différence diminue pour les arguments plus petits à range(..) / 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

dans ce cas xrange(100) est seulement environ 20% plus efficace.

1
répondu Evgeni Sergeev 2015-05-30 11:23:20

tout le monde l'a beaucoup expliqué. Mais je voulais voir par moi-même. J'utilise python3. Donc, j'ai ouvert le moniteur de ressources (dans Windows!), et d'abord exécuté la commande suivante en premier:

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

, puis vérifié le changement dans la mémoire "en cours d'utilisation". C'était insignifiant. Puis, j'ai lancé le code suivant:

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

et il a fallu une grande partie de la mémoire pour l'utiliser, instantanément. Et, j'ai été convaincu. Vous pouvez l'essayer pour vous-même.

Si vous utilisez Python 2X, puis remplacer "range ()" par "xrange ()" dans le premier code et 'list(range())' avec 'range()'.

1
répondu ANKUR SATYA 2017-07-24 10:37:26

Range retourne une list tandis que xrange retourne un xrange objet qui prend la même mémoire indépendamment de la taille de la gamme,comme dans ce cas,un seul élément est généré et disponible par itération tandis que dans le cas d'utiliser la gamme, tous les éléments sont générés à la fois et sont disponibles dans la mémoire.

0
répondu user299567 2015-01-03 06:31:21

gamme: - la gamme peuplera tout à la fois.ce qui signifie que chaque nombre de la gamme occupera la mémoire.

xrange: - xrange est quelque chose comme générateur ,il viendra dans l'image quand vous voulez la gamme de nombres mais vous ne voulez pas qu'ils soient stockés,comme quand vous voulez utiliser pour boucle.donc la mémoire est efficace.

0
répondu tejaswini teju 2017-04-03 17:36:19

De l'aide docs.

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 différence est apparente. En Python 2.x, range renvoie une liste, xrange renvoie un objet xrange qui est itérable.

En Python 3.x, range devient xrange de Python 2.x, et xrange est supprimé.

0
répondu Rajendra Uppal 2017-08-19 05:28:15

voir ce post pour trouver la différence entre la gamme et xrange:

pour citer:

range retourne exactement ce que vous pensez: une liste de entiers, d'une longueur définie commençant par 0. xrange , cependant, renvoie un "objet xrange " , qui agit beaucoup comme un itérateur

-1
répondu Oko 2012-10-21 13:54:56