Funcția Python enumerate(), explicată cu exemple

Explorarea funcției enumerate() în Python

Acest ghid detaliat îți va arăta cum să utilizezi eficient funcția enumerate() în Python. Această funcție oferă o metodă elegantă și concisă de a itera printr-o structură de date, accesând simultan atât elementele, cât și indicii lor.

Vom începe prin a analiza metodele tradiționale de accesare a elementelor și indicilor folosind bucle simple for, după care vom explora în detaliu funcționalitatea și sintaxa funcției enumerate(). Vom exemplifica totul prin cod practic.

Să începem!

Iterații folosind bucle for în Python

Un iterabil în Python este orice obiect care permite parcurgerea secvențială a elementelor sale. Listele, tuplurile, dicționarele și șirurile de caractere sunt exemple comune de iterabile.

Să considerăm o listă de cumpărături ca exemplu:

shopping_list = ["fructe", "biscuiți", "cereale", "batoane proteice", "post-it-uri"]

Buclele for permit parcurgerea iterabilelor. Sintaxa generală este:

for element in <iterabil>:
    # acțiuni asupra elementului

# element: variabila de iterare
# <iterabil>: orice structură iterabilă din Python (listă, tuplu, dicționar, șir etc.)

Aplicând această sintaxă, putem parcurge lista de cumpărături și afișa fiecare articol:

for element in shopping_list:
    print(element)

# Ieșire
fructe
biscuiți
cereale
batoane proteice
post-it-uri

Această metodă oferă acces direct la elemente. Cu toate acestea, uneori este necesar să accesăm și indicii elementelor, pe lângă elementele în sine.

Putem utiliza o variabilă index, pe care o incrementăm în corpul buclei:

index = 0
for element in shopping_list:
  print(f"index:{index}, {element}")
  index += 1

# Ieșire
index:0, fructe
index:1, biscuiți
index:2, cereale
index:3, batoane proteice
index:4, post-it-uri

Însă, aceasta nu este cea mai optimă metodă. Dacă uităm să incrementăm indexul, codul nu va funcționa corect:

index = 0
for element in shopping_list:
  print(f"index:{index}, {element}")
  # indexul nu este actualizat
  # indexul rămâne mereu 0

# Ieșire
index:0, fructe
index:0, biscuiți
index:0, cereale
index:0, batoane proteice
index:0, post-it-uri

O altă tehnică frecventă este utilizarea buclei for împreună cu funcția range().

Utilizarea funcției range() pentru accesarea indicilor

Funcția încorporată len() returnează lungimea oricărui obiect Python. Putem obține lungimea listei de cumpărături apelând len(shopping_list), care în acest caz este 5.

len(shopping_list)
# Ieșire: 5

Funcția range() generează un obiect interval ce poate fi folosit în bucle. Atunci când iterăm printr-un range(stop), obținem indicii 0, 1, 2, …, stop-1.

Setând stop = len(listă), obținem o serie de indici valizi. Astfel, folosind range(), putem accesa atât indicele, cât și elementul corespunzător:

for index in range(len(shopping_list)):
    print(f"index:{index}, element: {shopping_list[index]}")

# Ieșire
index:0, element: fructe
index:1, element: biscuiți
index:2, element: cereale
index:3, element: batoane proteice
index:4, element: post-it-uri

Totuși, aceasta nu este metoda recomandată de Python pentru accesarea simultană a indicilor și elementelor.

Sintaxa funcției enumerate() în Python

Funcția enumerate() simplifică accesul la elemente și indicii lor, folosind sintaxa generală:

enumerate(<iterabil>, start = 0)
  • <iterabil>: Parametru obligatoriu, reprezentând orice iterabil Python (listă, tuplu etc.).
  • start: Parametru opțional, definind indexul de pornire. Dacă nu este specificat, valoarea implicită este zero.

Apelând enumerate(shopping_list), obținem un obiect enumerate:

enumerate(shopping_list)
# <enumerate object at 0x...>

Nu putem parcurge direct obiectul enumerate. Pentru a-l vizualiza, îl putem converti într-o listă:

list(enumerate(shopping_list))

# Ieșire
[(0, 'fructe'),
 (1, 'biscuiți'),
 (2, 'cereale'),
 (3, 'batoane proteice'),
 (4, 'post-it-uri')]

O altă metodă de a accesa elementele unui obiect enumerate este folosirea funcției next(). Această funcție returnează următorul element dintr-un iterator.

Funcția next() apelează intern metoda __next__ a obiectului iterator pentru a prelua elementele succesive.

Să atribuim obiectul enumerate variabilei shopping_list_enum:

shopping_list_enum = enumerate(shopping_list)

La primul apel al funcției next(shopping_list_enum), vom obține tuplul (0, 'fructe'), reprezentând indexul zero și elementul de la acel index.

Continuând apelurile la next(), vom primi elementele succesive împreună cu indicii lor:

next(shopping_list_enum)
# (0, 'fructe')
next(shopping_list_enum)
# (1, 'biscuiți')
next(shopping_list_enum)
# (2, 'cereale')
next(shopping_list_enum)
# (3, 'batoane proteice')
next(shopping_list_enum)
# (4, 'post-it-uri')

Dacă apelăm next() după ce am epuizat toate elementele, vom obține o eroare StopIteration:

next(shopping_list_enum)
# Eroare: StopIteration

Funcția enumerate() returnează indicii și elementele succesive doar atunci când este necesar, nu le calculează în prealabil. Această caracteristică este utilă în proiectele Python care necesită eficiență în gestionarea memoriei, în special atunci când se iterează prin iterabile mari.

Exemple de utilizare a funcției enumerate()

Acum, vom modifica bucla for prezentată anterior, folosind funcția enumerate().

Știm că iterarea printr-un obiect enumerate returnează un tuplu cu indexul și elementul. Putem despacheta acest tuplu în două variabile: index și element:

for index, element in enumerate(shopping_list):
        print(f"index:{index}, element:{element}")

# Ieșire
index:0, element:fructe
index:1, element:biscuiți
index:2, element:cereale
index:3, element:batoane proteice
index:4, element:post-it-uri

Mai departe, vom vedea cum putem defini o valoare de pornire personalizată.

Utilizarea enumerate() cu valoare de pornire personalizată

În mod implicit, indexarea în Python începe de la zero. Totuși, dacă dorim ca indexarea să înceapă de la 1, sau de la orice altă valoare, putem specifica o valoare de pornire personalizată.

În exemplul listei de cumpărături, pentru a începe numărătoarea de la 1, setăm start = 1:

for index, element in enumerate(shopping_list, 1):
        print(f"index:{index}, element:{element}")

# Ieșire
index:1, element:fructe
index:2, element:biscuiți
index:3, element:cereale
index:4, element:batoane proteice
index:5, element:post-it-uri

Când specificăm o valoare de pornire personalizată, trebuie să ne asigurăm că o specificăm ca al doilea argument pozițional.

Inversând accidental ordinea argumentelor, vom primi o eroare:

for index, element in enumerate(1,shopping_list):
        print(f"index:{index}, element:{element}")

# Ieșire: Eroare TypeError

Pentru a evita astfel de erori, putem specifica start ca argument cuvânt cheie:

for index, element in enumerate(shopping_list, start = 1):
        print(f"index:{index}, element:{element}")

# Ieșire
index:1, element:fructe
index:2, element:biscuiți
index:3, element:cereale
index:4, element:batoane proteice
index:5, element:post-it-uri

Am învățat cum să folosim funcția enumerate() cu listele Python. Putem folosi această funcție și pentru a itera prin șiruri, dicționare și tupluri.

Utilizarea enumerate() cu tupluri Python

Să presupunem că lista_cumpărături este un tuplu. Tuplurile sunt colecții similare listelor, dar sunt imuabile, adică nu pot fi modificate. Încercarea de a modifica un tuplu va genera o eroare.

Următorul exemplu inițializează lista_cumpărături ca tuplu:

shopping_list = ("fructe", "biscuiți", "cereale", "batoane proteice", "post-it-uri")
type(shopping_list)
# Tuplu

Încercarea de a modifica primul element din tuplu va genera o eroare, deoarece un tuplu este o colecție imuabilă:

shopping_list[0] = 'legume'

# Ieșire: Eroare TypeError

Putem verifica funcționarea lui enumerate() cu tupluri rulând următorul cod:

shopping_list = ("fructe","biscuiți","cereale","batoane proteice","post-it-uri")
for index, element in enumerate(shopping_list):
    print(f"index:{index}, element:{element}")

Utilizarea enumerate() cu șiruri Python

Funcția enumerate() poate fi folosită și pentru a parcurge șiruri de caractere, accesând simultan caracterele și indicii lor.

Iată un exemplu:

sir_py="Fluture"
for index, caracter in enumerate(sir_py):
  print(f"index {index}: {caracter}")

# Ieșire
index 0: F
index 1: l
index 2: u
index 3: t
index 4: u
index 5: r
index 6: e

Din rezultatul de mai sus, vedem că caracterele, împreună cu indicii lor (0-6), au fost afișate.

Concluzie

  • Buclele for permit accesul la elemente și menținerea unui contor sau variabilă index separat.
  • Funcția range() generează indici valizi, permițând accesul la elemente prin indexare.
  • Funcția enumerate() (cu sintaxa enumerate(iterabil)) este modalitatea recomandată de Python pentru accesarea simultană a elementelor și indicilor lor. În mod implicit, indexul începe de la 0.
  • Putem specifica o valoare de start personalizată cu sintaxa enumerate(iterabil, start).
  • Funcția enumerate() funcționează cu tupluri, șiruri, dicționare și, în general, cu orice iterabil Python.

Sperăm că acest ghid detaliat despre funcția enumerate() a fost util. Nu ezita să experimentezi și să continui să aprofundezi cunoștințele tale de Python. Spor la codat!