Was ist der Unterschied zwischen Range- und Xrange-Funktionen in Python 2.X?

719

Anscheinend ist xrange schneller, aber ich habe keine Ahnung, warum es schneller ist (und kein Beweis außer dem Anekdoten, dass es schneller ist) oder was darüber hinaus anders ist

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

Antworten:

817

In Python 2.x:

  • rangeErstellt eine Liste. Wenn Sie dies tun range(1, 10000000), wird eine Liste mit 9999999Elementen im Speicher erstellt .

  • xrange ist ein Sequenzobjekt, das träge ausgewertet wird.

In Python 3 rangeentspricht dies Python xrange, und um die Liste zu erhalten, müssen Sie verwenden list(range(...)).

Charles
quelle
65
xrange ist nto genau ein Generator, aber es wertet träge aus und verhält sich wie ein Generator.
Vaibhav Mishra
47
xrange(x).__iter__()ist ein Generator.
Uhr
34
Warum haben sie xrange gemacht, anstatt range faul zu machen?
Rob Grant
22
@ RobertGrant, haben sie. In Python 3. (Das konnten sie in der Python 2.x-Zeile nicht tun, da alle Änderungen abwärtskompatibel sein müssen.)
Paul Draper
12
@Ratul bedeutet, dass jedes ibei Bedarf und nicht bei der Initialisierung ausgewertet wird.
Onilol
223

range erstellt eine Liste. Wenn Sie dies tun range(1, 10000000), wird eine Liste mit 9999999Elementen im Speicher erstellt .

xrange ein Generator ist, so dass es eine Sequenz Objekt a ist , dass auswertet lazily.

Dies ist wahr, wird aber in Python 3 .range()von Python 2 implementiert .xrange(). Wenn Sie die Liste tatsächlich generieren müssen, müssen Sie Folgendes tun:

list(range(1,100))
Corey
quelle
3
Ich sehe kein großes Problem (in Bezug auf das Brechen bestehender Anwendungen), da der Bereich hauptsächlich zum Generieren von Indizes diente, die für Schleifen verwendet werden sollen, wie "für i im Bereich (1, 10):"
Benjamin Autin
10
+1 Vielen Dank für diese Antwort. Die Informationen zum Ersetzen des Bereichs durch Python 3 durch xrange sind sehr nützlich. Ich habe tatsächlich jemandem gesagt, er solle stattdessen xrange oder range verwenden, und er hat gesagt, dass es in Python 3 keine Rolle spielt. Deshalb habe ich bei Google nach weiteren Informationen gesucht und diese Antwort wurde
Cervo,
Was ist falsch daran, xrangeeinen Generator anzurufen? Es ist eine Funktion, die eine yieldAnweisung enthält, und laut Glossar werden solche Funktionen Generatoren genannt.
Winterlicht
@winterlight, denke der richtige Begriff dafür ist Iterator. Generatoren sollten auch empfangen können.
McSinyx
112

Denken Sie daran, timeittesten Sie mit dem Modul, welcher der kleinen Codeausschnitte schneller ist!

$ 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

Persönlich verwende ich immer .range(), es sei denn, ich habe es mit wirklich großen Listen zu tun - wie Sie zeitlich sehen können, beträgt der zusätzliche Aufwand für eine Liste mit einer Million Einträgen nur 0,04 Sekunden. Und wie Corey betont, wird Python 3.0 .xrange()verschwinden und .range()Ihnen trotzdem ein gutes Iteratorverhalten geben.

John Fouhy
quelle
12
+1 für ein zeitgemäßes Beispiel. Hinweis: laufen in Windows cmd es doppelte Anführungszeichen zu verwenden , ist erforderlich, das heißt“So Code wird.python -m timeit "for i in xrange(1000000):" " pass"
Stiel
10
Der Hauptvorteil von xrange ist das Gedächtnis, nicht die Zeit.
Endolith
3
+1 für die praktische Antwort: Verwenden Sie die Reichweite, sofern sie nicht groß ist . Übrigens sind sie konzeptionell identisch, richtig? Seltsamerweise bedeutet das keine Antwort.
Bob Stein
6
Wenn xrange schneller ist und keinen Speicherplatz beansprucht, warum sollte Range verwendet werden?
Austin Mohr
8
Ich stimme Ihrer Aussage im Allgemeinen zu, aber Ihre Bewertung ist falsch: the extra overhead is only 0.04 secondsIst nicht die richtige Sichtweise, (90.5-51.1)/51.1 = 1.771 times slowerist richtig, weil sie vermittelt, dass dies möglicherweise ein Engpass sein kann, wenn dies die Kernschleife Ihres Programms ist. Wenn dies jedoch ein kleiner Teil ist, ist 1,77x nicht viel.
Chacham15
65

xrangespeichert nur die Bereichsparameter und generiert die Nummern bei Bedarf. Die C-Implementierung von Python beschränkt ihre Argumente derzeit jedoch auf 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]

Beachten Sie, dass es in Python 3.0 nur gibt rangeund es sich wie 2.x verhält, xrangejedoch ohne die Einschränkungen für minimale und maximale Endpunkte.

efotinis
quelle
39

xrange gibt einen Iterator zurück und speichert jeweils nur eine Zahl. Der Bereich speichert die gesamte Liste der Zahlen.

Ben Hoffstein
quelle
9
xrangegibt keinen Iterator zurück.
Abarnert
and only keeps one number in memory at a timeund wo der Rest platziert ist,
führe
5
@SIslam Wenn es den Anfang, das Ende und den aktuellen Stand kennt, kann es den nächsten nacheinander berechnen.
Justin Meiners
30

Verbringen Sie einige Zeit mit der Bibliotheksreferenz . Je vertrauter Sie damit sind, desto schneller finden Sie Antworten auf solche Fragen. Besonders wichtig sind die ersten Kapitel über eingebaute Objekte und Typen.

Der Vorteil des xrange-Typs besteht darin, dass ein xrange-Objekt unabhängig von der Größe des Bereichs, den es darstellt, immer dieselbe Speichermenge benötigt. Es gibt keine konsistenten Leistungsvorteile.

Eine andere Möglichkeit, schnelle Informationen zu einem Python-Konstrukt zu finden, ist die Dokumentzeichenfolge und die Hilfefunktion:

print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
Antti Rasinen
quelle
1
Die Bibliothek ist gut, aber es ist nicht immer so einfach, die Antwort auf Ihre Frage zu bekommen.
Teifion
2
Gehen Sie zur Bibliotheksreferenz, drücken Sie Strg + F, suchen Sie nach dem Bereich und Sie erhalten zwei Ergebnisse. Es ist nicht sehr aufwendig, die Antwort auf diese Frage zu finden.
David Locke
1
Die Bibliotheksreferenz funktioniert nicht. Kannst du es bitte aktualisieren?
mk ..
14

Ich bin schockiert, dass niemand doc gelesen hat :

Diese Funktion ist sehr ähnlich, range()gibt jedoch ein xrangeObjekt anstelle einer Liste zurück. Dies ist ein undurchsichtiger Sequenztyp, der dieselben Werte wie die entsprechende Liste liefert, ohne sie alle gleichzeitig zu speichern. Der Vorteil von xrange()over range()ist minimal (da xrange()die Werte immer noch erstellt werden müssen, wenn Sie danach gefragt werden), außer wenn ein sehr großer Bereich auf einer Maschine mit Speichermangel verwendet wird oder wenn alle Elemente des Bereichs niemals verwendet werden (z. B. wenn die Schleife verwendet wird) normalerweise beendet mit break).

Kishor Pawar
quelle
13

range erstellt eine Liste. Wenn Sie also range (1, 10000000) ausführen, wird eine Liste mit 10000000 Elementen im Speicher erstellt. xrange ist ein Generator und wird daher träge ausgewertet.

Dies bringt Ihnen zwei Vorteile:

  1. Sie können längere Listen iterieren, ohne eine zu erhalten MemoryError.
  2. Wenn Sie die Iteration vorzeitig beenden, verschwenden Sie keine Zeit damit, die gesamte Liste zu erstellen.
Lucas S.
quelle
12

In diesem einfachen Beispiel finden Sie den Vorteil von xrangeover range:

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

Das obige Beispiel spiegelt im Fall von nichts wesentlich Besseres wider xrange.

Schauen Sie sich nun den folgenden Fall an range, in dem es im Vergleich zu wirklich sehr, sehr langsam ist 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

Mit erstellt rangees bereits eine Liste von 0 bis 100000000 (zeitaufwändig), xrangeist jedoch ein Generator und generiert nur Zahlen basierend auf dem Bedarf, dh wenn die Iteration fortgesetzt wird.

In Python-3 ist die Implementierung der rangeFunktionalität dieselbe wie xrangein Python-2, während sie xrangein Python-3 abgeschafft wurde

Viel Spaß beim Codieren !!

User_Targaryen
quelle
11

Es ist aus Optimierungsgründen.

range () erstellt eine Liste von Werten von Anfang bis Ende (0 .. 20 in Ihrem Beispiel). Dies wird in sehr großen Bereichen zu einer teuren Operation.

xrange () ist dagegen viel optimierter. Der nächste Wert wird nur bei Bedarf berechnet (über ein xrange-Sequenzobjekt) und es wird keine Liste aller Werte erstellt, wie dies bei range () der Fall ist.

QAZ
quelle
9

range(x,y)Gibt eine Liste jeder Zahl zwischen x und y zurück, wenn Sie eine forSchleife verwenden, und rangeist dann langsamer. In der Tat rangehat einen größeren Indexbereich. range(x.y)druckt eine Liste aller Zahlen zwischen x und y aus

xrange(x,y)Gibt zurück, xrange(x,y)aber wenn Sie eine forSchleife verwendet haben, xrangeist dies schneller. xrangehat einen kleineren Indexbereich. xrangedruckt nicht nur aus, xrange(x,y)sondern behält auch alle darin enthaltenen Nummern bei.

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

Wenn Sie eine forSchleife verwenden, würde es funktionieren

[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

Es gibt keinen großen Unterschied bei der Verwendung von Loops, obwohl es einen Unterschied beim Drucken gibt!

Supercolbat
quelle
8

range (): range (1, 10) gibt eine Liste mit 1 bis 10 Zahlen zurück und speichert die gesamte Liste.

xrange (): Wie range (), aber anstatt eine Liste zurückzugeben, wird bei Bedarf ein Objekt zurückgegeben, das die Zahlen im Bereich generiert. Für Schleifen ist dies etwas schneller als range () und speichereffizienter. xrange () Objekt wie ein Iterator und generiert die Zahlen bei Bedarf. (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
Tushar.PUCSD
quelle
6

Einige der anderen Antworten erwähnt , dass Python 3 2.x ist eliminiert rangeund umbenannt 2.x ist xrangezu range. Wenn Sie jedoch nicht 3.0 oder 3.1 verwenden (was niemand sein sollte), handelt es sich tatsächlich um einen etwas anderen Typ.

Wie die 3.1-Dokumente sagen:

Bereichsobjekte haben nur ein sehr geringes Verhalten: Sie unterstützen nur die Indizierung, Iteration und die lenFunktion.

In Version 3.2+ rangehandelt es sich jedoch um eine vollständige Sequenz - sie unterstützt erweiterte Slices und alle Methoden collections.abc.Sequencemit derselben Semantik wie a list. * *

Und zumindest in CPython und PyPy (die einzigen zwei 3.2+ Implementierungen , die derzeit vorhanden ist ), hat es auch konstante Zeit Implementierungen der indexund countMethoden und die inBetreiber (solange man es nur ganze Zahlen passieren). Dies bedeutet, dass das Schreiben 123456 in rin 3.2+ vernünftig ist, während es in 2.7 oder 3.1 eine schreckliche Idee wäre.


* Die Tatsache , dass issubclass(xrange, collections.Sequence)Erträge Truein 2,6-2,7 und 3,0-3,1 ist ein Fehler , der in 3.2 und nicht zurückportiert wurde behoben.

abarnert
quelle
6

In Python 2.x.

range (x) gibt eine Liste zurück, die mit x Elementen im Speicher erstellt wird.

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

xrange (x) gibt ein xrange-Objekt zurück, das ein Generatorobjekt ist, das die Zahlen bei Bedarf generiert. Sie werden während der for-Schleife (Lazy Evaluation) berechnet.

Für Schleifen ist dies etwas schneller als range () und speichereffizienter.

>>> b = xrange(5)
>>> b
xrange(5)
Siyaram Malav
quelle
xrange()ist kein Generator. xrange(n).__ iter __ () `ist.
th3an0maly
5

Beim Testen des Bereichs gegen xrange in einer Schleife (ich weiß, ich sollte timeit verwenden , aber dies wurde mithilfe eines einfachen Beispiels zum Listenverständnis schnell aus dem Speicher gehackt) fand ich Folgendes:

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)

was gibt:

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

Oder verwenden Sie xrange in der for-Schleife:

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

Wird mein Snippet richtig getestet? Irgendwelche Kommentare zur langsameren Instanz von xrange? Oder ein besseres Beispiel :-)

Dave Everitt
quelle
2
Das einmalige Ausführen eines solchen Benchmarks liefert keine genauen Timing-Ergebnisse. Es gibt immer eine Abweichung. Es könnte entweder GC oder ein anderer Prozess sein, der die CPU stiehlt ... alles. Das ist, warum Benchmarks normalerweise 10-100-1000 -... ausgeführt werden
Vajk Hermecz
Dies ist nur ein hastiger Ausdruck - ich habe ihn einige Male ausgeführt, aber nur bis zu 100, und xrangeschien etwas schneller zu sein, obwohl der Vergleich mit Python 3 jetzt überflüssig ist.
Dave Everitt
3
Dafür ist da timeit. Es kümmert sich darum, viele Male zu laufen, GC zu deaktivieren, die beste Uhr anstelle von timeusw. zu verwenden
abarnert
4

xrange () und range () in Python funktionieren ähnlich wie für den Benutzer, aber der Unterschied ergibt sich, wenn wir darüber sprechen, wie der Speicher bei Verwendung beider Funktionen zugewiesen wird.

Wenn wir range () verwenden, weisen wir allen von ihm generierten Variablen Speicher zu. Daher wird die Verwendung mit der größeren Zahl nicht empfohlen. von zu generierenden Variablen.

xrange () hingegen generiert jeweils nur einen bestimmten Wert und kann nur mit der for-Schleife verwendet werden, um alle erforderlichen Werte zu drucken.

Lakshaya Maheshwari
quelle
3

range generiert die gesamte Liste und gibt sie zurück. xrange nicht - es generiert bei Bedarf die Nummern in der Liste.

Eddie Deyo
quelle
2

xrange verwendet einen Iterator (generiert Werte im laufenden Betrieb), range gibt eine Liste zurück.

Hacama
quelle
2

Was?
rangeGibt zur Laufzeit eine statische Liste zurück.
xrangeGibt ein object(das sich wie ein Generator verhält, obwohl es sicherlich keines ist) zurück, aus dem bei Bedarf Werte generiert werden.

Wann welche verwenden?

  • Verwenden xrangeSie diese Option, wenn Sie eine Liste für einen gigantischen Bereich erstellen möchten, z. B. 1 Milliarde, insbesondere wenn Sie ein "speicherempfindliches System" wie ein Mobiltelefon haben.
  • Verwenden rangeSie diese Option, wenn Sie die Liste mehrmals durchlaufen möchten.

PS: Python 3.x die rangeFunktion == Python 2.x - xrangeFunktion.

kmario23
quelle
xrangegibt kein Generatorobjekt zurück.
Abarnert
Wenn ich das richtig verstehe, wird es hier (für Python 2.x) so erklärt: wiki.python.org/moin/Generators
kmario23
Dann ist das Wiki falsch. (Ich weiß nicht, wer der "SH" ist, der diesen Kommentar hinzugefügt und unterschrieben hat.) Die offizielle Dokumentation ist richtig; Sie können es selbst testen und sehen, ob es sich um einen Generator oder eine Sequenz handelt.
Abarnert
OK. Aber es ist immer noch verwirrend, nachdem ich dies gelesen habe: stackoverflow.com/questions/135041/…
kmario23
1
Die lustige Frage ist, was zu tun ist, wenn der Dolmetscher nicht mit den offiziellen Dokumenten oder mit einem anderen Dolmetscher
übereinstimmt.
2

Jeder hat es sehr erklärt. Aber ich wollte, dass es es selbst sieht. Ich benutze Python3. Also öffnete ich den Ressourcenmonitor (unter Windows!) Und führte zuerst den folgenden Befehl aus:

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

und überprüfte dann die Änderung im 'In Use'-Speicher. Es war unbedeutend. Dann habe ich den folgenden Code ausgeführt:

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

Und es brauchte sofort einen großen Teil des Speichers, um verwendet zu werden. Und ich war überzeugt. Sie können es selbst versuchen.

Wenn Sie Python 2X verwenden, ersetzen Sie 'range ()' im ersten Code durch 'xrange ()' und 'list (range ())' durch 'range ()'.

ANKUR SATYA
quelle
2

Aus den Hilfedokumenten.

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

Der Unterschied ist offensichtlich. Gibt in Python 2.x rangeeine Liste und xrangeein iterierbares xrange-Objekt zurück.

Wird in Python 3.x rangezu xrangePython 2.x und xrangewird entfernt.

Rajendra Uppal
quelle
1

Bei einer Anforderung zum Scannen / Drucken von 0-N-Elementen funktionieren Bereich und x-Bereich wie folgt.

range () - Erstellt eine neue Liste im Speicher und nimmt die gesamten 0 bis N Elemente (insgesamt N + 1) und druckt sie aus. xrange () - Erstellt eine Iteratorinstanz, die die Elemente durchsucht und nur das aktuell angetroffene Element im Speicher behält, wodurch immer die gleiche Speichermenge verwendet wird.

Wenn sich das erforderliche Element nur etwas am Anfang der Liste befindet, spart dies viel Zeit und Speicher.

Einige Zweifel
quelle
1
xrangeerstellt keine Iteratorinstanz. Es wird ein xrangeObjekt erstellt, das iterierbar ist, aber kein Iterator - fast (aber nicht ganz) eine Sequenz wie eine Liste.
Abarnert
1

Range gibt eine Liste zurück, während xrange ein xrange- Objekt zurückgibt , das unabhängig von der Bereichsgröße denselben Speicher belegt. In diesem Fall wird nur ein Element pro Iteration generiert und ist verfügbar, während bei Verwendung von range alle Elemente gleichzeitig und generiert werden sind im Speicher verfügbar.

user299567
quelle
1

Der Unterschied verringert sich für kleinere Argumente zu 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

In diesem Fall xrange(100)ist nur etwa 20% effizienter.

Evgeni Sergeev
quelle
1

range: -range füllt alles auf einmal. Dies bedeutet, dass jede Nummer des Bereichs den Speicher belegt.

xrange: -xrange ist so etwas wie ein Generator. Es wird angezeigt, wenn Sie den Zahlenbereich möchten, aber nicht möchten, dass sie gespeichert werden, wie wenn Sie in for loop.so speichereffizient verwenden möchten.

tejaswini teju
quelle
1

Darüber hinaus ist if do list(xrange(...))gleichbedeutend mit range(...).

Ist listalso langsam.

xrangeBeendet die Sequenz auch wirklich nicht vollständig

Deshalb ist es keine Liste, sondern ein xrangeObjekt

U10-Vorwärts
quelle
1

range() in Python 2.x

Diese Funktion ist im Wesentlichen die alte range()Funktion, die in Python verfügbar war, 2.xund gibt eine Instanz eines listObjekts zurück, das die Elemente im angegebenen Bereich enthält.

Diese Implementierung ist jedoch zu ineffizient, wenn eine Liste mit einem Zahlenbereich initialisiert werden soll. Zum Beispiel for i in range(1000000)wäre die Ausführung eines Befehls sehr teuer, sowohl in Bezug auf den Speicher als auch in Bezug auf die Zeitnutzung, da die Speicherung dieser Liste im Speicher erforderlich ist.


range()in Python 3.xund xrange()in Python2.x

Python 3.xführte eine neuere Implementierung von ein range()(während die neuere Implementierung bereits in Python 2.xüber die xrange()Funktion verfügbar war ).

Das range()nutzt eine Strategie, die als Lazy Evaluation bekannt ist. Anstatt eine große Liste von Elementen im Bereich zu erstellen, führt die neuere Implementierung die Klasse ein range, ein leichtes Objekt, das die erforderlichen Elemente im angegebenen Bereich darstellt, ohne sie explizit im Speicher zu speichern (dies mag nach Generatoren klingen, aber das Konzept der verzögerten Auswertung ist es anders).


Betrachten Sie als Beispiel Folgendes:

# Python 2.x
>>> a = range(10)
>>> type(a)
<type 'list'>
>>> b = xrange(10)
>>> type(b)
<type 'xrange'>

und

# Python 3.x
>>> a = range(10)
>>> type(a)
<class 'range'>
Giorgos Myrianthous
quelle
-2

In diesem Beitrag finden Sie den Unterschied zwischen Bereich und Bereich:

Zitieren:

rangeGibt genau das zurück, was Sie denken: Eine Liste aufeinanderfolgender Ganzzahlen mit einer definierten Länge, die mit 0 beginnt xrange, gibt jedoch ein "xrange-Objekt" zurück , das sich stark wie ein Iterator verhält

Oko
quelle
2
Mir ist klar, dass dies 5 Jahre alt ist, aber dieser Beitrag ist in fast allem falsch. xrangeist kein Iterator. Die von zurückgegebene Liste rangeunterstützt die Iteration (eine Liste ist so ziemlich das prototypische Beispiel einer iterierbaren Liste). Der Gesamtnutzen von xrangeist nicht "minimal". Und so weiter.
Abarnert