Funkce Python enumerate() vysvětlená na příkladech

V tomto návodu se seznámíte s použitím funkce `enumerate()` v programovacím jazyce Python.

Pythonovská funkce `enumerate()` nabízí elegantní způsob, jak získat přístup k prvkům iterovatelného objektu spolu s jejich indexy.

Začneme tím, že si ukážeme, jak se k prvkům a indexům přistupuje pomocí jednoduchého cyklu, a následně probereme syntaxi funkce `enumerate()` v Pythonu. Během toho si také ukážeme praktické příklady.

Pojďme na to!

Jak iterovat pomocí cyklu `for` v Pythonu

Jakýkoliv objekt v Pythonu, který je možné procházet a přistupovat k jeho prvkům – jeden po druhém, se nazývá iterovatelný. Mezi takové objekty patří například seznamy, n-tice, slovníky a řetězce.

Pro ilustraci si představme nákupní seznam definovaný v následujícím kódu:

shopping_list = ["ovoce","sušenky","cereálie","proteinové tyčinky","samolepicí bločky"]

V Pythonu lze k iteraci přes libovolný iterovatelný objekt použít cyklus `for`. Syntaxe pro tento postup je následující:

for prvek in <iterovatelný_objekt>:
    # proveď něco s prvkem

# prvek: proměnná cyklu
# <iterovatelný_objekt>: jakýkoliv iterovatelný objekt v Pythonu: seznam, n-tice, slovník, řetězec atd.

Nyní, s využitím této syntaxe, projdeme nákupní seznam a zpřístupníme si jednotlivé položky.

for prvek in shopping_list:
  print(prvek)

# Výstup
ovoce
sušenky
cereálie
proteinové tyčinky
samolepicí bločky

Tento způsob nám umožňuje přímo přistupovat k jednotlivým prvkům. Nicméně, někdy je potřeba kromě samotných prvků znát i jejich index.

Můžeme použít proměnnou pro index, kterou budeme navyšovat uvnitř těla cyklu, jak je ukázáno níže:

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

# Výstup
index:0, ovoce
index:1, sušenky
index:2, cereálie
index:3, proteinové tyčinky
index:4, samolepicí bločky

Tento přístup však není nejefektivnější. Pokud zapomeneme index navýšit, kód nebude fungovat správně.

index = 0
for prvek in shopping_list:
  print(f"index:{index}, {prvek}")
  # index není uvnitř cyklu aktualizován
  # index je vždy 0

# Výstup
index:0, ovoce
index:0, sušenky
index:0, cereálie
index:0, proteinové tyčinky
index:0, samolepicí bločky

Další běžný způsob použití cyklu `for` je ve spojení s funkcí `range()`. Tomu se budeme věnovat v další sekci.

Použití funkce `range()` pro přístup k indexu

Vestavěná funkce `len()` v Pythonu vrací délku jakéhokoli Python objektu. Můžeme tedy použít `len()` s argumentem `shopping_list`, abychom získali jeho délku (v tomto případě 5).

len(shopping_list)
# Výstup: 5

Funkce `range()` vrací rozsah, který můžeme použít v cyklu. Při iteraci přes rozsah (`stop`) získáme indexy 0, 1, 2,…, `stop`-1.

Nastavením `stop` na délku seznamu získáme seznam platných indexů. Takže pomocí funkce `range()` můžeme přistupovat jak k indexu, tak i k odpovídajícímu prvku, jak ukazuje následující příklad:

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

# Výstup
index:0, prvek: ovoce
index:1, prvek: sušenky
index:2, prvek: cereálie
index:3, prvek: proteinové tyčinky
index:4, prvek: samolepicí bločky

Tento způsob však není doporučovaným pythonovským přístupem pro současný přístup k indexům i prvkům.

Syntaxe funkce `enumerate()` v Pythonu

Funkce `enumerate()` v Pythonu umožňuje přistupovat k prvkům společně s jejich indexy pomocí následující obecné syntaxe:

enumerate(<iterovatelný_objekt>, start = 0)

V této syntaxi:

  • `<iterovatelný_objekt>` je povinný parametr a může to být jakýkoli iterovatelný objekt v Pythonu, například seznam nebo n-tice.
  • `start` je volitelný parametr, který určuje, od kterého indexu se má začít počítat. Pokud není hodnota `start` zadána, výchozí hodnota je nula.

Nyní můžeme zavolat funkci `enumerate()` s `shopping_list`, která vrátí objekt `enumerate`, jak je ukázáno níže.

enumerate(shopping_list)
<enumerate object at 0x7f91b4240410>

Objekt `enumerate` není iterovatelný. Provedeme tedy jeho konverzi na seznam v Pythonu.

list(enumerate(shopping_list))

# Výstup
[(0, 'ovoce'),
 (1, 'sušenky'),
 (2, 'cereálie'),
 (3, 'proteinové tyčinky'),
 (4, 'samolepicí bločky')]

Další možností, jak přistupovat k prvkům objektu `enumerate` je volání funkce `next()`. s objektem `enumerate` jako argumentem. Funkce `next()` v Pythonu vrací další prvek z iterátoru.

Interně funkce `next()` volá metodu `__next__` na objektu iterátoru pro načtení následných prvků.

Přiřadíme objekt `enumerate` proměnné `shopping_list_enum`.

shopping_list_enum = enumerate(shopping_list)

Při prvním zavolání `next()` s `shopping_list_enum` dostaneme index nula a prvek na indexu 0: n-tici (0, ‚ovoce‘).

Pokračováním ve volání funkce `next()` získáme další prvky spolu s jejich indexy, jak je popsáno níže.

next(shopping_list_enum)
# (0, 'ovoce')
next(shopping_list_enum)
# (1, 'sušenky')
next(shopping_list_enum)
# (2, 'cereálie')
next(shopping_list_enum)
# (3, 'proteinové tyčinky')
next(shopping_list_enum)
# (4, 'samolepicí bločky')

Co se stane, když zavoláme funkci `next()` poté, co už byly všechny prvky zpřístupněny a dostali jsme se na konec seznamu? Dojde k chybě `StopIteration`.

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

StopIteration:

Funkce `enumerate()` vrací indexy a prvky postupně, pouze když jsou potřeba, a nejsou vypočítávány předem. V projektech v Pythonu, kde je důležitá efektivita paměti, je vhodné používat `enumerate()`, když potřebujete iterovat přes velké iterovatelné objekty.

Příklady použití funkce `enumerate()` v Pythonu

Nyní, když jsme si osvojili syntaxi pro použití funkce `enumerate()`, upravíme cyklus `for`, který jsme měli dříve.

Z předchozí sekce víme, že iterací přes objekt `enumerate` se vrací n-tice s indexem a prvkem. Tuto n-tici můžeme rozbalit do dvou proměnných: `index` a `prvek`.

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

# Výstup
index:0, prvek:ovoce
index:1, prvek:sušenky
index:2, prvek:cereálie
index:3, prvek:proteinové tyčinky
index:4, prvek:samolepicí bločky

Dále se podíváme, jak nastavit vlastní počáteční hodnotu.

Použití `enumerate()` s vlastní počáteční hodnotou

Python sleduje nulové indexování, takže výchozí hodnota indexu je 0. Pokud však potřebujete indexy v čitelné formě – počínaje 1 nebo libovolným jiným indexem, můžete zadat vlastní počáteční hodnotu.

Pokud v příkladu s nákupním seznamem chceme začít počítat od 1, nastavíme `start = 1`.

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

# Výstup
index:1, prvek:ovoce
index:2, prvek:sušenky
index:3, prvek:cereálie
index:4, prvek:proteinové tyčinky
index:5, prvek:samolepicí bločky

Při zadávání vlastní počáteční hodnoty se však musíte ujistit, že ji zadáváte jako druhý poziční argument.

Pokud omylem prohodíte pořadí iterovatelného objektu a počáteční hodnoty, dojde k chybě, jak je uvedeno níže:

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

# Výstup
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-5dbf7e2749aa> in <module>()
----> 1 for index, prvek in enumerate(1,shopping_list):
      2   print(f"index:{index}, prvek:{prvek}")

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

Abyste se těmto chybám vyhnuli, můžete zadat `start` jako argument klíčového slova, jak je ukázáno níže.

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

# Výstup
index:1, prvek:ovoce
index:2, prvek:sušenky
index:3, prvek:cereálie
index:4, prvek:proteinové tyčinky
index:5, prvek:samolepicí bločky

Zatím jsme se naučili používat funkci `enumerate()` se seznamy v Pythonu. Tuto funkci však můžeme použít i pro iteraci přes řetězce, slovníky a n-tice.

Použití funkce `enumerate()` s n-ticemi v Pythonu

Předpokládejme, že náš nákupní seznam je n-tice. N-tice v Pythonu jsou také kolekce – podobně jako seznamy, ale jsou neměnné. Proto je nemůžeme modifikovat a pokus o to povede k chybě.

Následující kód inicializuje `shopping_list` jako n-tici.

shopping_list = ("ovoce","sušenky","cereálie","proteinové tyčinky","samolepicí bločky")
type(shopping_list)
# Tuple

Pokud se pokusíme upravit první prvek v n-tici, dojde k chybě, protože n-tice v Pythonu je neměnná kolekce.

shopping_list[0] = 'zelenina'

# Výstup
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-ffdafa961600> in <module>()
----> 1 shopping_list[0] = 'zelenina'

TypeError: 'tuple' object does not support item assignment

▶ Spuštěním následujícího kódu ověříte, že funkce `enumerate()` funguje s n-ticemi dle očekávání.

shopping_list = ("ovoce","sušenky","cereálie","proteinové tyčinky","samolepicí bločky")
for index, prvek in enumerate(shopping_list):
    print(f"index:{index}, prvek:{prvek}")

Použití funkce `enumerate()` s řetězci v Pythonu

Funkci `enumerate()` v Pythonu můžeme také použít pro procházení řetězců a současný přístup ke znakům a indexům.

Zde je příklad:

py_str="Motýl"
for index, znak in enumerate(py_str):
  print(f"index {index}: {znak}")

# Výstup
index 0: M
index 1: o
index 2: t
index 3: ý
index 4: l

Z výše uvedeného výstupu je zřejmé, že znaky spolu s jejich indexy (0-4) byly vypsány.

Závěr👩🏽‍💻

Zde je souhrn toho, co jsme se naučili:

  • K přístupu k prvkům a udržování samostatné proměnné pro index můžeme použít cyklus `for`.
  • Případně můžeme použít funkci `range()` pro získání platných indexů a přístup k prvkům pomocí indexování v seznamu.
  • Doporučený Python způsob je použití funkce `enumerate()` se syntaxí: `enumerate(iterovatelný_objekt)`. Ve výchozím nastavení začíná index od 0.
  • Můžeme zadat vlastní počáteční hodnotu pomocí syntaxe `enumerate(iterovatelný_objekt, start)`, abychom získali index začínající hodnotou `start` a odpovídající prvky.
  • Funkci `enumerate()` můžeme použít při práci s n-ticemi, řetězci, slovníky a obecně s jakýmkoli iterovatelným objektem v Pythonu.

Doufám, že vám tento návod o funkci `enumerate()` byl užitečný. Dále se můžete naučit, jak najít index prvku v seznamech v Pythonu. Pokračujte v programování!