Kurs

In diesem Tutorial erfährst du, was die Funktion enumerate() in Python ist, wann sie zum Einsatz kommt, welche Objekte sie erzeugt, wie die Syntax aussieht und wie sie funktioniert. Anschließend schauen wir uns Beispiele für die Aufzählung verschiedener Objekttypen in Python an, welche Alternativen es zu enumerate() gibt und warum diese sich für die gleiche Aufgabe weniger eignen.
Was ist enumerate in Python und wann wird es verwendet?
Die Funktion enumerate() ist eine eingebaute Python-Funktion. Sie nimmt ein iterierbares Objekt entgegen (eine Sammlung von Elementen oder jedes andere Python-Objekt, das Iteration unterstützt, z. B. Tuples, Listen, Sets oder Strings), iteriert intern darüber und gibt ein Enumerate-Objekt zurück. Anders gesagt: Die Funktion weist jedem Element eines Iterables einen zählenden Index in Einerschritten zu und hilft uns, beim Durchlaufen eines Objekts die Iterationen nachzuverfolgen. Das resultierende Enumerate-Objekt können wir anschließend in eine Liste, ein Tuple oder ein Dictionary umwandeln (mit list(), tuple() bzw. dict()) oder direkt darüber iterieren, um gleichzeitig auf Elemente und ihre Indizes zuzugreifen.
enumerate() ist in puncto Speicher- und Recheneffizienz praktisch, weil sie im Vergleich zu reinen For-Schleifen Index und Element in einem Schritt liefert.
Syntax
Die Syntax von enumerate() ist sehr einfach:
enumerate(iterable, start=0)
Hier ist iterable das zu enumerierende Objekt und start ein optionaler Parameter, der den Startindex des Zählers festlegt (standardmäßig gilt der in Python übliche 0-basierte Index).
Wichtig: Das Anwenden von enumerate() auf ein Iterable verändert das Ursprungsobjekt nicht. Stattdessen solltest du das entstehende Enumerate-Objekt einer Variablen zuweisen, wenn du es weiterverwenden willst.
Schauen wir uns nun an, wie die Funktion mit unterschiedlichen Python-Iterables arbeitet.
Eine Liste enumerieren
Zuerst wenden wir enumerate() auf eine Python-Liste an:
drinks = ['tea', 'coffee', 'cappuccino', 'lemonade']
enumerated_drinks = enumerate(drinks)
print(type(enumerated_drinks))
print(enumerated_drinks)
Ausgabe:
<class 'enumerate'>
<enumerate object at 0x000002DC3A1145C0>
Der Typ des resultierenden Objekts ist enumerate. Beim Ausdrucken sehen wir erneut den Objekttyp und die Speicheradresse. Versuchen wir, wie bei einer Liste oder einem Tuple, direkt auf das erste Element zuzugreifen:
print(enumerated_drinks[0])
Ausgabe:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_5948/1233607596.py in <module>
----> 1 print(enumerated_drinks[0])
TypeError: 'enumerate' object is not subscriptable
Wir erhalten einen Fehler: Die Bestandteile eines Enumerate-Objekts lassen sich so nicht ansprechen. Dafür müssen wir es in eine Liste, ein Tuple oder ein Dictionary umwandeln oder direkt über das Enumerate-Objekt iterieren. Wandeln wir es in eine Liste um:
list_enumerated_drinks = list(enumerated_drinks)
print(list_enumerated_drinks)
Ausgabe:
[(0, 'tea'), (1, 'coffee'), (2, 'cappuccino'), (3, 'lemonade')]
Jetzt erkennen wir die innere Struktur: Jedes Element ist ein 2-Tuple, dessen erstes Element der Index aus der Ursprungsliste ist und dessen zweites Element das jeweilige Listenelement. Wir können per Indexzugriff auflisten:
print(list_enumerated_drinks[0])
print(list_enumerated_drinks[0][1])
Ausgabe:
(0, 'tea')
tea
Wandeln wir nun ein von der Ursprungsliste erzeugtes Enumerate-Objekt in ein Tuple um und setzen zusätzlich den optionalen Parameter start auf 1:
tuple_enumerated_drinks = tuple(enumerate(drinks, start=1))
print(tuple_enumerated_drinks)
Ausgabe:
((1, 'tea'), (2, 'coffee'), (3, 'cappuccino'), (4, 'lemonade'))
Die Struktur ist identisch zur zuvor erzeugten Liste. Dieses Mal beginnt die Zählung jedoch bei 1 und wirkt damit „menschlicher“ als der 0-basierte Python-Index.
Ein interessantes Hilfsmittel im Zusammenhang mit Enumerate-Objekten ist die Funktion next(). Erstellen wir enumerated_drinks neu und probieren sie aus:
enumerated_drinks = enumerate(drinks)
print(next(enumerated_drinks))
print(next(enumerated_drinks))
print(next(enumerated_drinks))
print(next(enumerated_drinks))
print(next(enumerated_drinks))
Ausgabe:
(0, 'tea')
(1, 'coffee')
(2, 'cappuccino')
(3, 'lemonade')
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_5948/330134057.py in <module>
4 print(next(enumerated_drinks))
5 print(next(enumerated_drinks))
----> 6 print(next(enumerated_drinks))
StopIteration:
Jeder Aufruf liefert das nächste Element des Enumerate-Objekts zurück (erneut ein 2-Tuple aus Index und Element). Sind alle Elemente verbraucht, ist das Objekt erschöpft und next() löst einen StopIteration-Fehler aus. Versuchen wir nun, dieses Enumerate-Objekt in eine Liste umzuwandeln, sehen wir, dass sie leer ist:
print(list(enumerated_drinks))
Ausgabe:
[]
Das bedeutet: Mit jedem next()-Aufruf wird ein Element entnommen; das Objekt schrumpft, bis es vollständig erschöpft ist. Dasselbe Verhalten sehen wir gleich auch bei For-Schleifen.
Wenn du mehr über Python-Listen und weitere Grundlagen lernen willst, schau dir den Kurs Introduction to Python von DataCamp an.
Ein Tuple enumerieren
Die Anwendung von enumerate() auf ein Tuple funktioniert genauso wie bei einer Liste:
drinks = ('tea', 'coffee', 'cappuccino', 'lemonade')
enumerated_drinks = enumerate(drinks)
print(enumerated_drinks)
Ausgabe:
<enumerate object at 0x000002DC3A098D40>
Wieder erhalten wir ein Enumerate-Objekt, dessen Elemente nicht per gewöhnlichem Indexzugriff erreichbar sind. Wandeln wir es diesmal in ein Dictionary um:
dict_enumerated_drinks = dict(enumerated_drinks)
print(dict_enumerated_drinks)
Ausgabe:
{0: 'tea', 1: 'coffee', 2: 'cappuccino', 3: 'lemonade'}
Jedes Key:Value-Paar entspricht einem Index-Element-Paar. Auf Werte greifen wir ganz Python-typisch zu:
print(dict_enumerated_drinks[0])
print(dict_enumerated_drinks[3])
Ausgabe:
tea
lemonade
Wenn du tiefer in Dictionaries und pandas einsteigen willst, sieh dir den Kurs Intermediate Python an.
Einen String enumerieren
Strings sind Zeichenketten und damit ebenfalls iterierbar. Wir können also auch für einen String ein Enumerate-Objekt erstellen:
enumerated_hello_world = enumerate('Hello, World!', start=10)
print(enumerated_hello_world)
Ausgabe:
<enumerate object at 0x000002DC3A145C40>
Wie zuvor wandeln wir dieses Objekt in eine Liste um:
list_enumerated_hello_world = list(enumerated_hello_world)
print(list_enumerated_hello_world)
Ausgabe:
[(10, 'H'), (11, 'e'), (12, 'l'), (13, 'l'), (14, 'o'), (15, ','), (16, ' '), (17, 'W'), (18, 'o'), (19, 'r'), (20, 'l'), (21, 'd'), (22, '!')]
Wir sehen wieder 2-Tuples: Der erste Wert ist der Zähler für das jeweilige Zeichen (hier ab 10), der zweite das Zeichen selbst. Leerzeichen und Satzzeichen werden ebenfalls gezählt.
Erstellen wir enumerated_hello_world erneut, diesmal ohne start=10, und rufen mehrmals next() auf:
enumerated_hello_world = enumerate('Hello, World!')
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
print(next(enumerated_hello_world))
# Creating a list from the remaining enumerate object
print(list(enumerated_hello_world))
Ausgabe:
(0, 'H')
(1, 'e')
(2, 'l')
(3, 'l')
(4, 'o')
(5, ',')
[(6, ' '), (7, 'W'), (8, 'o'), (9, 'r'), (10, 'l'), (11, 'd'), (12, '!')]
In der letzten Zeile beenden wir die next()-Aufrufe und wandeln das verbleibende Enumerate-Objekt in eine Liste um. Die Liste enthält die restlichen Zeichen, die nach mehreren next()-Anwendungen übrig waren.
Enumerate in der For-Schleife
Zum Schluss sehen wir uns an, wie enumerate() zusammen mit einer For-Schleife funktioniert:
for item in enumerate(['tea', 'coffee', 'cappuccino', 'lemonade']):
print(item)
Ausgabe:
(0, 'tea')
(1, 'coffee')
(2, 'cappuccino')
(3, 'lemonade')
Bei jeder Iteration wird das entsprechende Index-Element-Tuple zurückgegeben, ganz wie bei next(). Auch hier gilt: Das Enumerate-Objekt verliert bei jeder Iteration seine Elemente. Zur Veranschaulichung schreiben wir den Code um und prüfen nach Abschluss der Iteration die Länge der resultierenden Liste:
drinks = ['tea', 'coffee', 'cappuccino', 'lemonade']
enumerated_drinks = enumerate(drinks)
for item in enumerated_drinks:
print(item)
print(list(enumerated_drinks))
Ausgabe:
(0, 'tea')
(1, 'coffee')
(2, 'cappuccino')
(3, 'lemonade')
[]
Wie schon bei next() wird ein Enumerate-Objekt durch Iteration schrittweise erschöpft.
Zurück zum vorherigen Beispiel: Wie greifen wir aus jedem 2-Tuple separat auf beide Elemente zu? Dafür fügen wir eine weitere Iterationsvariable hinzu und packen die Tuples aus:
for count, drink in enumerate(['tea', 'coffee', 'cappuccino', 'lemonade']):
print(count, drink)
Ausgabe:
0 tea
1 coffee
2 cappuccino
3 lemonade
Hier geben wir pro Tuple zwei Variablen zurück: eine für den Index und eine für das Element selbst.
Dasselbe lässt sich auch ohne enumerate() erreichen. Beispielsweise mit einer Zählvariable außerhalb der Schleife, die wir bei jeder Iteration um 1 erhöhen:
count = 0
for drink in ['tea', 'coffee', 'cappuccino', 'lemonade']:
print(count, drink)
count += 1
Ausgabe:
0 tea
1 coffee
2 cappuccino
3 lemonade
Alternativ können wir range() und len() auf einer vordefinierten Liste (oder einem Tuple, String etc.) kombinieren:
drinks = ['tea', 'coffee', 'cappuccino', 'lemonade']
for count in range(len(drinks)):
print(count, drinks[count])
Ausgabe:
0 tea
1 coffee
2 cappuccino
3 lemonade
In beiden Alternativen können wir den Startwert der Zählung ebenfalls anpassen:
count = 1
for drink in ['tea', 'coffee', 'cappuccino', 'lemonade']:
print(count, drink)
count += 1
print('\n')
drinks = ['tea', 'coffee', 'cappuccino', 'lemonade']
for count in range(len(drinks)):
print(count + 1, drinks[count])
Ausgabe:
1 tea
2 coffee
3 cappuccino
4 lemonade
1 tea
2 coffee
3 cappuccino
4 lemonade
Im Vergleich zur Verwendung von enumerate() sind beide Ansätze jedoch umständlicher, fehleranfälliger (z. B. wenn wir vergessen, den Zähler manuell zu erhöhen) und benötigen mehr Code. Deshalb ist enumerate() der pythonischste Ansatz, sobald wir bei jeder Iteration sowohl Index als auch Element benötigen.
Fazit
In diesem Tutorial hast du die Funktion enumerate() in Python umfassend kennengelernt: ihre Einsatzszenarien, mögliche Alternativen und warum sie diesen meist überlegen ist. Viele Einsteiger kennen enumerate() noch nicht, und selbst erfahrene Programmierer nutzen diese äußerst hilfreiche Funktion nicht immer.
Wenn du mehr über enumerate() erfahren möchtest, schau dir den Kurs Python Data Science Toolbox (Part 2) an. Er behandelt Iteratoren und Iterables ausführlich und bietet interaktive Übungen, um neue Kompetenzen zu festigen. Außerdem findest du unter Learn Python with DataCamp weitere Python-Kurse, Lernpfade, Spickzettel, Tutorials, Python-Zertifizierungen und Assessments.