Функција Питхон енумерате(), објашњена примерима

Ovaj vodič će vas upoznati sa načinom korišćenja funkcije `enumerate()` u programskom jeziku Python.

Funkcija `enumerate()` u Pythonu nudi elegantan i koncizan način da pristupite elementima unutar iterabilnog objekta, uz istovremeno dobijanje njihovih indeksa.

Započećemo pregledom kako se pristupa elementima i njihovim indeksima koristeći standardnu `for` petlju, a zatim ćemo preći na detaljno razmatranje sintakse i upotrebe Pythonove funkcije `enumerate()`. Usput ćemo ilustrovati sve primere kodom.

Krenimo odmah.

Iteracija pomoću `for` petlje u Pythonu

U Pythonu, svaki objekat preko kojeg možemo iterirati i pristupiti njegovim pojedinačnim elementima – jedan po jedan – naziva se iterabilni objekat. Prema tome, Python liste, torke, rečnici i stringovi spadaju u iterabilne objekte.

Posmatrajmo kao primer listu za kupovinu, definisanu u sledećem bloku koda:

shopping_list = ["voće","keksi","žitarice","proteinske pločice","lepljivi listići"]

U Pythonu, za iteriranje kroz bilo koji iterabilni objekat, možete koristiti `for` petlju. Opšta sintaksa je sledeća:

for stavka in <iterabilni_objekat>:
    # izvrši operaciju nad stavkom

# stavka: promenljiva petlje
# <iterabilni_objekat>: bilo koji iterabilni objekat u Pythonu: lista, torka, rečnik, string, itd.

Sada, primenom ove sintakse, proći ćemo kroz `shopping_list` i pristupiti svakom elementu pojedinačno.

for stavka in shopping_list:
  print(stavka)

# Izlaz
voće
keksi
žitarice
proteinske pločice
lepljivi listići

Ovakva konstrukcija nam omogućava direktan pristup elementima. Međutim, ponekad je neophodno pristupiti i indeksima elemenata, a ne samo samim elementima.

Jedan od načina je korišćenje promenljive indeksa, koju uvećavamo unutar tela petlje, kao što je prikazano u nastavku:

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

# Izlaz
indeks:0, voće
indeks:1, keksi
indeks:2, žitarice
indeks:3, proteinske pločice
indeks:4, lepljivi listići

Ipak, ovo nije najefikasniji način. Ako zaboravite da uvećate indeks, vaš kod neće raditi kako je predviđeno.

index = 0
for stavka in shopping_list:
  print(f"indeks:{index}, {stavka}")
  # izostalo uvećavanje indeksa unutar petlje
  # indeks se ne menja i uvek je 0

# Izlaz
indeks:0, voće
indeks:0, keksi
indeks:0, žitarice
indeks:0, proteinske pločice
indeks:0, lepljivi listići

Druga uobičajena praksa je kombinovanje `for` petlje sa funkcijom `range()`. O tome ćemo više u narednom odeljku.

Upotreba funkcije `range()` za pristup indeksu

Ugrađena Python funkcija `len()` vraća dužinu bilo kog Python objekta. Dakle, pozivanjem funkcije `len()` sa argumentom `shopping_list` dobijamo dužinu `shopping_list` (u ovom slučaju, 5).

len(shopping_list)
# Izlaz: 5

Funkcija `range()` generiše objekat opsega koji se može koristiti u petlji. Kada se iterira kroz `range(stop)`, dobijaju se indeksi 0, 1, 2,…, `stop`-1.

Postavljanjem `stop` na vrednost `len(lista)`, dobijamo listu validnih indeksa. Dakle, koristeći funkciju `range()`, možemo pristupiti i indeksu i odgovarajućem elementu, kao što je prikazano ispod.

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

# Izlaz
indeks:0, stavka: voće
indeks:1, stavka: keksi
indeks:2, stavka: žitarice
indeks:3, stavka: proteinske pločice
indeks:4, stavka: lepljivi listići

Ipak, ovo nije preporučeni način za istovremeni pristup indeksima i elementima u Pythonu.

Sintaksa Python funkcije `enumerate()`

Python funkcija `enumerate()` omogućava pristup elementima zajedno sa njihovim indeksima koristeći sledeću opštu sintaksu:

enumerate(<iterabilni_objekat>, start = 0)

U gornjoj sintaksi:

  • `<iterabilni_objekat>` je obavezan parametar i može biti bilo koji Python iterabilni objekat, kao što je lista ili torka.
  • `start` je opcioni parametar koji definiše od kog indeksa počinje brojanje. Ako se ne navede vrednost za `start`, podrazumevana vrednost je nula.

Sada, pozivanjem funkcije `enumerate()` sa argumentom `shopping_list` dobija se objekat `enumerate`, kao što je prikazano u bloku koda ispod.

enumerate(shopping_list)
<enumerate object at 0x7f91b4240410>

Ne može se iterirati direktno kroz objekat `enumerate`. Dakle, hajde da konvertujemo `enumerate` objekat u Python listu.

list(enumerate(shopping_list))

# Izlaz
[(0, 'voće'),
 (1, 'keksi'),
 (2, 'žitarice'),
 (3, 'proteinske pločice'),
 (4, 'lepljivi listići')]

Drugi način da se pristupi elementima objekta `enumerate` je pozivanje funkcije `next()`, uz prosleđivanje `enumerate` objekta kao argumenta. U Pythonu, funkcija `next()` vraća sledeći element iz iteratora.

Interno, funkcija `next()` radi tako što poziva metodu `__next__` na objektu iteratora, kako bi preuzela sledeći element.

Dodelićemo `enumerate` objekat promenljivoj `shopping_list_enum`.

shopping_list_enum = enumerate(shopping_list)

Prvim pozivanjem funkcije `next()` sa argumentom `shopping_list_enum`, dobija se indeks nula i element sa indeksom 0: torka `(0, ‘voće’)`.

Daljim pozivanjem funkcije `next()` dobijaju se uzastopni elementi zajedno sa njihovim indeksima, kao što je prikazano u nastavku.

next(shopping_list_enum)
# (0, 'voće')
next(shopping_list_enum)
# (1, 'keksi')
next(shopping_list_enum)
# (2, 'žitarice')
next(shopping_list_enum)
# (3, 'proteinske pločice')
next(shopping_list_enum)
# (4, 'lepljivi listići')

Šta se događa ako pozovete funkciju `next()` nakon što ste pristupili svim elementima i došli do kraja liste? Dobićete grešku `StopIteration`.

next(shopping_list_enum)
# ---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-16-4220f68f6c7e> in <module>()
----> 1 next(shopping_list_enum)

StopIteration:

Funkcija `enumerate()` vraća uzastopne indekse i elemente samo kada je to potrebno i ne izračunava ih unapred. U Python projektima gde je efikasnost memorije bitna, možete koristiti funkciju `enumerate()` kada je potrebno iterirati kroz velike iterabilne objekte.

Primeri upotrebe Python funkcije `enumerate()`

Sada kada smo naučili sintaksu funkcije `enumerate()`, modifikujmo `for` petlju koju smo koristili ranije.

Iz prethodnog odeljka znamo da iteriranje kroz `enumerate` objekat vraća torke koje sadrže indeks i element. Ovu torku možemo raspakovati u dve promenljive: `indeks` i `stavka`.

for indeks, stavka in enumerate(shopping_list):
  print(f"indeks:{indeks}, stavka:{stavka}")

# Izlaz
indeks:0, stavka:voće
indeks:1, stavka:keksi
indeks:2, stavka:žitarice
indeks:3, stavka:proteinske pločice
indeks:4, stavka:lepljivi listići

Pogledajmo kako se može odrediti prilagođena početna vrednost indeksa.

`enumerate()` sa prilagođenom početnom vrednošću

U Pythonu se indeksi broje od nule, tako da je podrazumevana početna vrednost 0. Međutim, ako su vam potrebni indeksi u čitljivijem obliku — počevši od 1 ili bilo kog drugog broja, možete navesti prilagođenu početnu vrednost.

U slučaju liste za kupovinu, ako želite da brojanje počne od 1, postavite `start = 1`.

for indeks, stavka in enumerate(shopping_list,1):
  print(f"indeks:{indeks}, stavka:{stavka}")

# Izlaz
indeks:1, stavka:voće
indeks:2, stavka:keksi
indeks:3, stavka:žitarice
indeks:4, stavka:proteinske pločice
indeks:5, stavka:lepljivi listići

Imajte na umu da kada navodite prilagođenu početnu vrednost, morate je navesti kao drugi pozicioni argument.

Ako greškom zamenite redosled iterabilnog objekta i početne vrednosti, naići ćete na grešku, kao što je objašnjeno u bloku koda ispod.

for indeks, stavka in enumerate(1,shopping_list):
  print(f"indeks:{indeks}, stavka:{stavka}")

# Izlaz
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-5dbf7e2749aa> in <module>()
----> 1 for indeks, stavka in enumerate(1,shopping_list):
      2   print(f"indeks:{indeks}, stavka:{stavka}")

TypeError: 'list' object cannot be interpreted as an integer

Da biste izbegli ovakve greške, možete navesti `start` kao argument ključne reči, kao što je prikazano u nastavku.

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

# Izlaz
indeks:1, stavka:voće
indeks:2, stavka:keksi
indeks:3, stavka:žitarice
indeks:4, stavka:proteinske pločice
indeks:5, stavka:lepljivi listići

Do sada ste naučili kako da koristite funkciju `enumerate()` sa Python listama. Funkciju `enumerate` takođe možete koristiti za iteriranje kroz Python stringove, rečnike i torke.

Korišćenje funkcije `enumerate()` sa Python torkama

Pretpostavimo da je lista za kupovinu torka. U Pythonu, torke su takođe kolekcije — slične Python listama, ali su nepromenljive. Stoga se ne mogu menjati, a pokušaj izmene će dovesti do greške.

Sledeći fragment koda inicijalizuje `shopping_list` kao torku.

shopping_list = ("voće","keksi","žitarice","proteinske pločice","lepljivi listići")
type(shopping_list)
# Tuple

Ako pokušate da izmenite prvi element u torki, dobićete grešku jer je Python torka nepromenljiva kolekcija.

shopping_list[0] = 'povrće'

# Izlaz
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-ffdafa961600> in <module>()
----> 1 shopping_list[0] = 'povrće'

TypeError: 'tuple' object does not support item assignment

▶ Sada pokrenite sledeći fragment koda da biste proverili da li funkcija `enumerate()` radi kako se očekuje sa torkama.

shopping_list = ("voće","keksi","žitarice","proteinske pločice","lepljivi listići")
for indeks, stavka in enumerate(shopping_list):
    print(f"indeks:{indeks}, stavka:{stavka}")

Korišćenje funkcije `enumerate()` sa Python stringovima

Takođe možete koristiti Python funkciju `enumerate()` za iteriranje kroz stringove, pristupajući istovremeno i karakterima i njihovim indeksima.

Evo primera.

py_str="Leptir"
for indeks, char in enumerate(py_str):
  print(f"indeks {indeks}: {char}")

# Izlaz
indeks 0: L
indeks 1: e
indeks 2: p
indeks 3: t
indeks 4: i
indeks 5: r

Iz gornjeg izlaza vidimo da su karakteri ispisani zajedno sa svojim indeksima (0-5).

Zaključak👩🏽‍💻

Evo rezimea onoga što ste naučili.

  • Možete koristiti `for` petlje za pristup elementima uz održavanje odvojenog brojača ili promenljive indeksa.
  • Alternativno, možete koristiti funkciju `range()` da biste dobili važeće indekse i pristupali elementima putem indeksiranja unutar liste.
  • Kao preporučeni Python način, možete koristiti Python funkciju `enumerate()` sa sintaksom: `enumerate(iterabilni_objekat)`. Podrazumevano, brojanje ili indeks počinje od 0.
  • Možete navesti prilagođenu početnu vrednost koristeći sintaksu `enumerate(iterabilni_objekat, start)` da biste dobili indeks koji počinje od zadate vrednosti i odgovarajuće elemente.
  • Funkciju `enumerate` možete koristiti kada radite sa torkama, stringovima, rečnicima i uopšte, sa bilo kojim Python iterabilnim objektom.

Nadam se da vam je ovaj vodič o funkciji `enumerate()` bio koristan. Dalje, istražite kako da pronađete indeks elementa u Python listama. Nastavite sa kodiranjem!