In Python 2.x gibt range
eine Liste zurück, aber in Python 3.x gibt range
eine unveränderliche Sequenz vom Typ range
zurück.
Python 2.x:
>>> type(range(10))
<type 'list'>
>>> type(xrange(10))
<type 'xrange'>
Python 3.x:
>>> type(range(10))
<class 'range'>
In Python 2.x, wenn Sie ein iterable Objekt erhalten möchten, wie in Python 3.x, können Sie xrange
Funktion verwenden, die eine unveränderliche Sequenz des Typs xrange
zurückgibt.
Vorteil xrange
über range
in Python 2.x:
Der Vorteil xrange()
über range()
ist minimal (da xrange()
noch die Werte zu schaffen hat, wenn sie danach gefragt werden), außer wenn ein sehr großer Bereich ist Wird auf einem speicherhungrigen Computer verwendet oder wenn alle Elemente des Bereichs nie verwendet werden (z. B. wenn die Schleife normalerweise mit einem Abbruch beendet wird).
Hinweis:
Darüber hinaus ist die einzige offensichtliche Art und Weise die ganzen Zahlen von range()
erstellt zuzugreifen, ist durch sie zu durchlaufen,
Nope. Da range
Objekte in Python 3 unveränderliche Sequenzen sind, unterstützen sie auch die Indizierung. Zitiert aus der range
Funktion Dokumentation,
Ranges alle gemeinsamen Sequenzoperationen außer Verkettung implementieren und Wiederholung
...
Range-Objekte implementieren die collections.abc.Sequence
ABC und bieten Funktionen wie Eindämmungstests , Element Index Lookup, Slicing und Unterstützung für negative Indizes.
Zum Beispiel
>>> range(10, 20)[5]
15
>>> range(10, 20)[2:5]
range(12, 15)
>>> list(range(10, 20)[2:5])
[12, 13, 14]
>>> list(range(10, 20, 2))
[10, 12, 14, 16, 18]
>>> 18 in range(10, 20)
True
>>> 100 in range(10, 20)
False
All dies ist möglich mit dieser unveränderlichen range
Sequenz.
Kürzlich habe ich ein Problem konfrontiert und ich denke, es wäre angemessen, hier aufzunehmen. Betrachten Sie diese Python 3.x Code
from itertools import islice
numbers = range(100)
items = list(islice(numbers, 10))
while items:
items = list(islice(numbers, 10))
print(items)
Einer dieser Code erwarten würde alle zehn Zahlen als eine Liste drucken, bis 99. Aber es wäre unendlich laufen. Kannst du begründen warum?
Lösung
Da die range
eine unveränderliche Sequenz zurückgibt, nicht ein Iterator-Objekt. Wenn also islice
auf einem range
Objekt ausgeführt wird, beginnt es immer von Anfang an. Betrachten Sie es als Drop-In-Ersatz für eine unveränderliche Liste. Jetzt kommt die Frage, wie wirst du es reparieren? Es ist einfach, man muss nur einen Iterator daraus machen. Ändern Sie einfach
numbers = range(100)
zu
numbers = iter(range(100))
Nun numbers
ein Iterator-Objekt ist, und es erinnert sich, wie lange es vor iteriert wurde. Also, wenn die islice
es iteriert, beginnt es nur von der Stelle, wo es zuvor endete.
Ihr letzter Satz in Frage zu stellen ist falsch. 'range' Objekte implementieren'__getitem__'. – wim
mögliches Duplikat von [Lazy evaluation python] (http://stackoverflow.com/questions/20535342/lazy-evaluation-python) – devnull
Diese Frage ist sich der Unterschiede zwischen Python 2 und 3 nicht bewusst, und ist * nicht * ein Betrogener von dem einen verbunden. –