Toegang krijgen tot de index in 'Foreach' loops in Python

Vaak moet je bij het doorlopen van een verzameling items in Python ook een rangtelwoord hebben dat aan elk item is gekoppeld. Zo’n nummer wordt meestal het index.

De pythonische manier om toegang te krijgen tot de index terwijl u een foreach -loop doet, is door de ingebouwde functie te gebruiken enumerate().

enumerate() voegt een index toe aan elk item in een iterabele verzameling. Je kunt dan de list() ingebouwde functie gebruiken om een ​​lijst met tupels terug te krijgen.

>>> names = ['Bob', 'Alice', 'John', 'Cindy']
>>> list(enumerate(names))
[(0, 'Bob'), (1, 'Alice'), (2, 'John'), (3, 'Cindy')]

Let op, het indexeren van Python begint vanaf 0.

Als u echter wilt beginnen met indexeren vanaf 1 (bijvoorbeeld bij het afdrukken van rapportgegevens), wordt dit triviaal bereikt door een extra start argument door te geven aan enumerate.

>>> names = ['Bob', 'Alice', 'John', 'Cindy']
>>> list(enumerate(names), start=1)
[(1, 'Bob'), (2, 'Alice'), (3, 'John'), (4, 'Cindy')]

De bovenstaande aanpak is ook handig als u gegevens uit verschillende gegevensbronnen afdrukt maar een consistente index voor alle gegevensitems wilt hebben.

>>> data_source1 = ['Bob', 'Alice', 'John', 'Cindy']
>>> data_source2 = ['Sarah', 'Jeff', 'Emily', 'Adam']
>>> list(enumerate(data_source1, start=1))
[(1, 'Bob'), (2, 'Alice'), (3, 'John'), (4, 'Cindy')]
>>> list(enumerate(data_source2, start=len(data_source1) + 1))
[(5, 'Sarah'), (6, 'Jeff'), (7, 'Emily'), (8, 'Adam')]

Merk op dat u een Enumerate object niet naar een lijst hoeft te converteren . Het is zelf een itereerbaar dus kan het er direct overheen gaan.

>>> names = ['Bob', 'Alice', 'John', 'Cindy']
>>> for idx, name in enumerate(names):
...   print(name)
...
Bob
Alice
John
Cindy

Er kunnen andere manieren zijn om de index te bemachtigen terwijl u een verzameling items doorloopt, maar het gebruik enumerate() wordt als canoniek beschouwd en heeft de voorkeur.

Een andere optie zou zijn om een ​​afzonderlijke indexvariabele te gebruiken, deze handmatig te initialiseren en bij elke iteratie handmatig te verhogen. Een dergelijke benadering zou echter worden beschouwd als een heruitvinding van het wiel en afgekeurd.

Hier is een citaat uit PEP 279 waarin de enumerate() functie werd geïntroduceerd.

This PEP introduces a new built-in function, enumerate() to simplify a commonly used looping idiom. It provides all iterable collections with the same advantage that iteritems() affords to dictionaries – a compact, readable, reliable index notation.

Je kan vragen of er gevolgen zijn voor het gebruik enumerate van uw code. Nou, je bent vrij om alle metingen te doen, maar houd alsjeblieft in gedachten, dat enumerate is een idiomatische manier om toegang te krijgen tot een index van een iterabele in een for-each lus. Idiomatische code wordt aanbevolen door de Python-beheerders en zij zullen er alles aan doen om het efficiënt te laten werken.

En voor degenen onder u, die hieronder het meest nieuwsgierig zijn, is een mogelijke implementatie van enumerate() functie uit de bovengenoemde PEP.

def enumerate(collection):
   'Generates an indexed series:  (0,coll[0]), (1,coll[1]) ...'
   i = 0
   it = iter(collection)
   while 1:
       yield (i, it.next())
       i += 1