Die Python-Funktion range(start, stop, step) erzeugt eine immutable Sequenz von Ganzzahlen — perfekt für Zähl-Schleifen. Im Gegensatz zu einer Liste hält range die Werte nicht im Speicher, sondern berechnet sie bei Bedarf. Ein range(0, 1_000_000) belegt nur ein paar Bytes — egal wie groß die Sequenz ist.
Einleitung
range() ist Pythons Antwort auf die klassische C-/Java-Schleife for (int i = 0; i < n; i++). Der Aufruf for i in range(10) zählt von 0 bis 9. Drei Varianten:
range(stop)— von 0 bisstop - 1range(start, stop)— vonstartbisstop - 1range(start, stop, step)— mit konfigurierbarer Schrittweite (auch negativ)
Wichtig: Das stop ist exklusiv — range(5) liefert 0, 1, 2, 3, 4, nicht 5. Diese „half-open"-Konvention ist konsistent mit Pythons Slicing (a[0:5]).
range-Objekte sind echte Sequenzen — sie unterstützen Indexzugriff (r[3]), Slicing (r[2:5]) und len(). Sie sind außerdem unbegrenzt wiederverwendbar (anders als Generatoren) und vergleichen sich nach Inhalt: range(3) == range(0, 3, 1) → True.
Syntax
range(stop)
range(start, stop)
range(start, stop, step)start (Optional, Default 0) Erster Wert der Sequenz.
stop Obergrenze (exklusiv). Sequenz endet bei stop - 1 (bei positivem step).
step (Optional, Default 1) Schrittweite. Negativ für absteigende Sequenz. Darf nicht 0 sein.
Rückgabewert
Ein range-Objekt — eine immutable, lazy ausgewertete Sequenz von Ganzzahlen.
Beispiele
Einfache Verwendung
Der häufigste Anwendungsfall ist eine Schleife, die n-mal etwas tut — typischerweise mit range(n):
for i in range(5):
print(i)0
1
2
3
4Mit start und step
Mit zwei oder drei Argumenten lassen sich auch beliebige Sequenzen erzeugen — etwa nur gerade Zahlen:
print(list(range(2, 10))) # 2 bis 9
print(list(range(0, 20, 5))) # in 5er-Schritten
print(list(range(10, 0, -2))) # rückwärts[2, 3, 4, 5, 6, 7, 8, 9]
[0, 5, 10, 15]
[10, 8, 6, 4, 2]Speicher-Effizienz im Vergleich zu Listen
range ist O(1) im Speicherbedarf — egal wie groß die Sequenz. Eine entsprechende Liste belegt das 100.000-fache:
import sys
r = range(1_000_000)
l = list(r)
print(f"range: {sys.getsizeof(r):>10} Bytes")
print(f"list: {sys.getsizeof(l):>10} Bytes")range: 48 Bytes
list: 8000056 BytesIndexzugriff und Slicing
range-Objekte verhalten sich wie Sequenzen — Indexzugriff und Slicing funktionieren ohne vorherige Materialisierung:
r = range(0, 100, 10)
print(r[3]) # 30
print(r[-1]) # letztes Element
print(list(r[2:5])) # Slicing
print(50 in r) # Mitgliedschaft — schnell, nicht linear30
90
[20, 30, 40]
TruePraktische Beispiele
Listen elementweise mit Index iterieren
Wer sowohl Index als auch Wert braucht, verwendet enumerate() — range(len(seq)) ist unidiomatisch:
items = ["a", "b", "c", "d"]
# Unidiomatisch:
for i in range(len(items)):
print(i, items[i])
# Idiomatisch:
for i, x in enumerate(items):
print(i, x)0 a
1 b
2 c
3 d
0 a
1 b
2 c
3 dRückwärts iterieren
Drei gleichwertige Wege, um eine Liste rückwärts zu durchlaufen — reversed() ist meist am besten lesbar:
items = ["a", "b", "c"]
for i in range(len(items) - 1, -1, -1):
print(i, items[i])
# Idiomatischer:
for i, x in reversed(list(enumerate(items))):
print(i, x)2 c
1 b
0 a
2 c
1 b
0 aTabelle aus zwei Listen erzeugen
Mit einer einfachen Schleife und range(len(...)) lässt sich eine kleine Lookup-Tabelle aus parallelen Listen ablesen:
names = ["Alice", "Bob", "Cleo"]
ages = [17, 24, 31]
for i in range(len(names)):
print(f"{names[i]:6} → {ages[i]} Jahre")Alice → 17 Jahre
Bob → 24 Jahre
Cleo → 31 JahrePraktische Hinweise
stopist exklusiv —range(5)endet bei 4. Diese Konvention ist konsistent mit Slicing.x in range(...)ist O(1) — schneller Mitgliedschafts-Check (kein linearer Scan).- Negative Schritte:
range(10, 0, -1)zählt rückwärts — Vorsicht mit Vorzeichen-Mismatch (range(0, 10, -1)ist leer). - Float wird nicht akzeptiert —
rangeist int-only. Für Float-Sequenzennumpy.arange()oder eine Generator-Expression nutzen. - Verwandte Funktionen:
enumerate()(Index + Wert),zip()(parallele Iteration),itertools.count()(unbegrenzt).