Geschiedenis van de vraag
De functie enumerate() is geïntroduceerd in Python voor een gemakkelijke en idiomatische iteratie over elementen van een sequentie, terwijl je tegelijkertijd de huidige index krijgt. Dit is bijzonder belangrijk, omdat het voorheen vaak werd aanbevolen om handmatig een aparte teller bij te houden, wat als minder idiomatisch en minder leesbaar werd beschouwd.
Probleem
In lussen is het vaak nodig om niet alleen de huidige waarde te kennen, maar ook de index ervan in de sequentie. Handmatig beheer van indexen met behulp van een aparte variabele (i) en het aanroepen van range(len(seq)) leidt tot fouten (ongelijkheid tussen indexen en waarden, duplicatie van code) en vermindert de leesbaarheid.
Oplossing
enumerate() retourneert een lazy iterator die op elke stap een tuple (index, waarde) van het huidige element teruggeeft. Hiermee kun je elegant en betrouwbaar met indexen werken:
kleuren = ['rood', 'groen', 'blauw'] for idx, kleur in enumerate(kleuren): print(idx, kleur)
Iteratie begint bij nul, maar je kunt een andere startwaarde opgeven:
for idx, kleur in enumerate(kleuren, start=1): print(idx, kleur)
Belangrijke kenmerken:
enumerate() werkt met elke iterabele sequentie, retourneert een tuple (index, element)start op te geven, wat handig kan zijnKun je de indexuitvoer uitschakelen en alleen waarden behouden bij het werken met enumerate()?
Nee, enumerate() retourneert altijd paren (index, waarde). Als je alleen de waarde wilt, gebruik dan een gewone for-lus:
for waarde in mijn_lijst: print(waarde)
Kun je enumerate() gebruiken met niet-indexeerbare objecten, zoals generators?
Ja, enumerate() werkt met elk iterabel object, inclusief generators. De indexering gebeurt in de volgorde van het verschijnen van de waarden:
def mijn_gen(): for i in range(3): yield chr(ord('a')+i) for idx, val in enumerate(mijn_gen()): print(idx, val) # 0 a, 1 b, 2 c
Kun je automatisch een startindex anders dan 0 instellen, en wat gebeurt er bij negatieve waarden?
Ja, enumerate() heeft een argument start. Als je een negatieve waarde doorgeeft, begint de indexering vanaf deze waarde:
for idx, x in enumerate(['a', 'b', 'c'], start=-3): print(idx, x) # -3 a, -2 b, -1 c
range(len(seq)) in plaats van enumerate() voor het doorlopen van een lijst — dit maakt de code minder idiomatischIn het team wordt een grote codebasis onderhouden, vaak gebruik makend van:
for i in range(len(mijn_lijst)): process(i, mijn_lijst[i])
Voordelen:
Nadelen:
Na refactoring overstappen op:
for idx, val in enumerate(mijn_lijst): process(idx, val)
Voordelen:
Nadelen: