Geschichte der Frage
Die Funktion enumerate() wurde in Python eingeführt, um eine bequeme und idiomatische Iteration über Elemente einer Sequenz zu ermöglichen, während gleichzeitig der aktuelle Index erhalten bleibt. Dies ist besonders wichtig, da zuvor oft empfohlen wurde, einen separaten Zähler manuell zu erstellen, was als nicht idiomatisch und weniger lesbar betrachtet wurde.
Problem
In Schleifen ist es oft erforderlich, nicht nur den aktuellen Wert, sondern auch dessen Index in der Sequenz zu kennen. Die manuelle Handhabung von Indizes mit einer separaten Variablen (i) und dem Aufruf von range(len(seq)) führt zu Fehlern (Abweichung von Indizes und Werten, Code-Duplikation) und beeinträchtigt die Lesbarkeit.
Lösung
enumerate() gibt einen faulen Iterator zurück, der bei jedem Schritt ein Tuple (Index, Wert) des aktuellen Elements liefert. Damit kann man elegant und zuverlässig mit Indizes arbeiten:
colors = ['rot', 'grün', 'blau'] for idx, color in enumerate(colors): print(idx, color)
Die Iteration beginnt bei null, es kann jedoch jeder Startwert angegeben werden:
for idx, color in enumerate(colors, start=1): print(idx, color)
Schlüsselfunktionen:
enumerate() funktioniert mit jeder iterierbaren Sequenz und gibt ein Tuple (Index, Element) zurückstart, was nützlich sein kannKann man die Rückgabe des Indexes deaktivieren und nur Werte bei der Arbeit mit enumerate() behalten?
Nein, enumerate() gibt immer Paare (Index, Wert) zurück. Wenn nur der Wert benötigt wird, verwenden Sie eine normale for-Schleife:
for value in my_list: print(value)
Kann enumerat() mit nicht indizierbaren Objekten wie Generatoren verwendet werden?
Ja, enumerate() funktioniert mit jedem iterierbaren Objekt, einschließlich Generatoren. Die Indizierung erfolgt in der Reihenfolge, in der die Werte erscheinen:
def mygen(): for i in range(3): yield chr(ord('a')+i) for idx, val in enumerate(mygen()): print(idx, val) # 0 a, 1 b, 2 c
Kann man automatisch einen Startindex ungleich 0 festlegen und was passiert bei negativen Werten?
Ja, enumerate() hat das Argument start. Wenn ein negativer Wert übergeben wird, beginnt die Indizierung mit diesem Wert:
for idx, x in enumerate(['a', 'b', 'c'], start=-3): print(idx, x) # -3 a, -2 b, -1 c
range(len(seq)) anstelle von enumerate() zur Iteration über eine Liste — dies macht den Code weniger idiomatischIm Team wird großer Code unterstützt, oft verwendet man:
for i in range(len(mylist)): process(i, mylist[i])
Vorteile:
Nachteile:
Nach der Refaktorisierung wechselt man zu:
for idx, val in enumerate(mylist): process(idx, val)
Vorteile:
Nachteile: