Funkcja enumerate() w języku Python, wyjaśniona przykładami
Ten przewodnik przedstawi Ci działanie funkcji enumerate() w języku Python.
Funkcja enumerate() w Pythonie to elegancki sposób na iterację po elementach sekwencji, jednocześnie mając dostęp do ich pozycji.
Zacznijmy od analizy, jak można pobrać zarówno elementy, jak i ich indeksy za pomocą standardowej pętli. Następnie przejdziemy do zrozumienia składni funkcji enumerate(), prezentując przykłady krok po kroku.
Rozpocznijmy naukę!
Iteracja z użyciem pętli for w Pythonie
W Pythonie, każdy obiekt, który umożliwia przeglądanie jego składowych, nazywamy iterowalnym. Listy, krotki, słowniki i napisy są więc przykładami struktur iterowalnych.
Rozważmy listę zakupów, zdefiniowaną w poniższym fragmencie kodu:
shopping_list = ["owoce", "ciastka", "płatki", "batony proteinowe", "karteczki samoprzylepne"]
W Pythonie pętla for pozwala na przejście po każdym elemencie obiektu iterowalnego. Ogólna postać pętli for wygląda tak:
for element in <obiekt_iterowalny>:
# operacje na elemencie
# element: zmienna pętli
# <obiekt_iterowalny>: dowolny obiekt iterowalny Pythona: lista, krotka, słownik, napis, itd.
Wykorzystując tę strukturę, przejdźmy teraz przez naszą listę zakupów i wyświetlmy każdy jej składnik.
for element in shopping_list: print(element) # Wynik owoce ciastka płatki batony proteinowe karteczki samoprzylepne
Powyższa konstrukcja pozwala na bezpośredni dostęp do poszczególnych elementów. Czasem jednak potrzebujemy również informacji o ich pozycji.
Możemy użyć zmiennej, która będzie przechowywać aktualny indeks i będzie zwiększana wewnątrz pętli, jak widać poniżej:
indeks = 0
for element in shopping_list:
print(f"indeks:{indeks}, {element}")
indeks += 1
# Wynik
indeks:0, owoce
indeks:1, ciastka
indeks:2, płatki
indeks:3, batony proteinowe
indeks:4, karteczki samoprzylepne
To rozwiązanie nie jest jednak idealne. Zapomnienie o zwiększeniu indeksu może skutkować błędami w działaniu kodu.
indeks = 0
for element in shopping_list:
print(f"indeks:{indeks}, {element}")
# brak aktualizacji indeksu wewnątrz pętli
# indeks nigdy nie jest zmieniany i zawsze wynosi 0
# Wynik
indeks:0, owoce
indeks:0, ciastka
indeks:0, płatki
indeks:0, batony proteinowe
indeks:0, karteczki samoprzylepne
Innym podejściem jest wykorzystanie pętli for w połączeniu z funkcją range(), co omówimy w kolejnej części.
Wykorzystanie funkcji range() do uzyskania dostępu do indeksów
Wbudowana w Pythona funkcja len() zwraca długość dowolnego obiektu. Możemy zatem użyć len(shopping_list), aby uzyskać długość naszej listy zakupów (w tym przypadku jest to 5).
len(shopping_list) # Wynik: 5
Funkcja range() generuje sekwencję liczb, którą można wykorzystać w pętli. Przechodząc po sekwencji range(stop), uzyskujemy indeksy 0, 1, 2,…, stop-1.
Ustawiając stop na len(list), uzyskujemy listę poprawnych indeksów. Używając range(), możemy uzyskać dostęp zarówno do indeksu, jak i elementu, jak pokazano poniżej.
for indeks in range(len(shopping_list)):
print(f"indeks:{indeks}, element: {shopping_list[indeks]}")
# Wynik
indeks:0, element: owoce
indeks:1, element: ciastka
indeks:2, element: płatki
indeks:3, element: batony proteinowe
indeks:4, element: karteczki samoprzylepne
Jednak w Pythonie istnieje bardziej elegancki i zalecany sposób na jednoczesne uzyskiwanie dostępu do indeksów i elementów – funkcja enumerate().
Składnia funkcji enumerate() w Pythonie
Funkcja enumerate() umożliwia dostęp do elementów wraz z ich indeksami za pomocą następującej składni:
enumerate(<obiekt_iterowalny>, start = 0)
W powyższej składni:
<obiekt_iterowalny>to wymagany parametr – obiekt iterowalny (lista, krotka, itp.).startto opcjonalny parametr określający, od jakiej wartości ma zacząć się indeksowanie. Domyślniestartwynosi zero.
Wywołując funkcję enumerate() na shopping_list, otrzymujemy obiekt typu enumerate, co prezentuje poniższy kod:
enumerate(shopping_list) <enumerate at 0x7f91b4240410>
Obiekt typu enumerate nie może być bezpośrednio iterowany. Przekształćmy go zatem w listę:
list(enumerate(shopping_list)) # Wynik [(0, 'owoce'), (1, 'ciastka'), (2, 'płatki'), (3, 'batony proteinowe'), (4, 'karteczki samoprzylepne')]
Kolejnym sposobem na dostęp do elementów obiektu enumerate jest wywołanie funkcji next(), z obiektem enumerate jako argumentem. W Pythonie funkcja next() zwraca kolejny element iteratora.
Funkcja next() w tle wywołuje metodę __next__ iteratora, aby uzyskać kolejne elementy.
Przypiszmy obiekt enumerate do zmiennej shopping_list_enum.
shopping_list_enum = enumerate(shopping_list)
Pierwsze wywołanie next(shopping_list_enum) zwróci indeks zero i element o tym indeksie, czyli krotkę (0, 'owoce').
Wykonując kolejne wywołania funkcji next(), otrzymamy następne elementy wraz z ich indeksami, jak pokazano poniżej.
next(shopping_list_enum) # (0, 'owoce') next(shopping_list_enum) # (1, 'ciastka') next(shopping_list_enum) # (2, 'płatki') next(shopping_list_enum) # (3, 'batony proteinowe') next(shopping_list_enum) # (4, 'karteczki samoprzylepne')
Co się stanie, gdy wywołamy funkcję next() po osiągnięciu końca listy? Otrzymamy błąd StopIteration.
next(shopping_list_enum) # --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-16-4220f68f6c7e> in <module>() ----> 1 next(shopping_list_enum) StopIteration:
Funkcja enumerate() zwraca kolejne indeksy i elementy tylko wtedy, gdy są potrzebne, co jest korzystne z punktu widzenia wydajności. W projektach, w których optymalizacja pamięci jest kluczowa, zaleca się stosowanie enumerate() przy pracy z dużymi sekwencjami iterowalnymi.
Przykłady użycia funkcji enumerate() w Pythonie
Znając już składnię funkcji enumerate(), zmodyfikujmy naszą wcześniejszą pętlę for.
Z poprzedniej sekcji wiemy, że pętla po obiekcie enumerate zwraca krotkę z indeksem i elementem. Możemy tę krotkę rozpakować do dwóch zmiennych: indeks i element.
for indeks, element in enumerate(shopping_list):
print(f"indeks:{indeks}, element:{element}")
# Wynik
indeks:0, element:owoce
indeks:1, element:ciastka
indeks:2, element:płatki
indeks:3, element:batony proteinowe
indeks:4, element:karteczki samoprzylepne
Sprawdźmy teraz, jak zdefiniować niestandardową wartość startową indeksowania.
Użycie enumerate() z niestandardową wartością startową
Domyślnie indeksowanie w Pythonie zaczyna się od 0. Jeżeli jednak chcemy uzyskać indeksy czytelne dla użytkownika, zaczynające się od 1 lub innej wartości, możemy to łatwo zdefiniować.
W przypadku naszej listy_zakupów, jeśli chcemy, aby indeksy zaczynały się od 1, ustawiamy parametr start na 1.
for indeks, element in enumerate(shopping_list,1):
print(f"indeks:{indeks}, element:{element}")
# Wynik
indeks:1, element:owoce
indeks:2, element:ciastka
indeks:3, element:płatki
indeks:4, element:batony proteinowe
indeks:5, element:karteczki samoprzylepne
Należy jednak pamiętać, że niestandardowa wartość startowa musi być podana jako drugi argument pozycyjny.
Pomylenie kolejności iterowalnego obiektu i wartości startowej spowoduje błąd, co ilustruje poniższy fragment kodu.
for indeks, element in enumerate(1,shopping_list):
print(f"indeks:{indeks}, element:{element}")
# Wynik
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-5dbf7e2749aa> in <module>()
----> 1 for indeks, element in enumerate(1,shopping_list):
2 print(f"indeks:{indeks}, element:{element}")
TypeError: 'list' object cannot be interpreted as an integer
Aby uniknąć takich błędów, możemy określić wartość startową jako argument nazwany, jak pokazano poniżej.
for indeks, element in enumerate(shopping_list, start = 1):
print(f"indeks:{indeks}, element:{element}")
# Wynik
indeks:1, element:owoce
indeks:2, element:ciastka
indeks:3, element:płatki
indeks:4, element:batony proteinowe
indeks:5, element:karteczki samoprzylepne
Do tej pory nauczyliśmy się używać funkcji enumerate() z listami. Możemy ją także stosować z napisami, słownikami i krotkami.
Użycie enumerate() z krotkami w Pythonie
Załóżmy, że lista_zakupów jest krotką. Krotki, podobnie jak listy, są kolekcjami elementów, jednak są one niemodyfikowalne. Próba modyfikacji krotki spowoduje błąd.
Poniższy kod inicjalizuje shopping_list jako krotkę.
shopping_list = ("owoce", "ciastka", "płatki", "batony proteinowe", "karteczki samoprzylepne")
type(shopping_list)
# Tuple
Próba zmiany pierwszego elementu krotki spowoduje błąd, ponieważ krotki są niemodyfikowalne.
shopping_list[0] = 'warzywa' # Wynik --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-2-ffdafa961600> in <module>() ----> 1 shopping_list[0] = 'warzywa' TypeError: 'tuple' object does not support item assignment
▶ Uruchom poniższy kod, aby zobaczyć, czy funkcja enumerate() działa zgodnie z oczekiwaniami z krotkami.
shopping_list = ("owoce", "ciastka", "płatki", "batony proteinowe", "karteczki samoprzylepne")
for indeks, element in enumerate(shopping_list):
print(f"indeks:{indeks}, element:{element}")
Wykorzystanie enumerate() z napisami w Pythonie
Funkcję enumerate() w Pythonie możemy także użyć do iteracji po napisach, uzyskując dostęp do znaków i ich indeksów.
Oto przykład:
napis = "Motyl"
for indeks, znak in enumerate(napis):
print(f"indeks {indeks}: {znak}")
# Wynik
indeks 0: M
indeks 1: o
indeks 2: t
indeks 3: y
indeks 4: l
Jak widać, zostały wydrukowane znaki wraz z ich indeksami (0-4).
Podsumowanie 👩🏽💻
Oto kluczowe punkty, które omówiliśmy:
- Pętla
forpozwala na dostęp do elementów oraz na utrzymywanie osobnej zmiennej z indeksem. - Funkcja
range()pozwala na generowanie sekwencji indeksów, dzięki czemu mamy dostęp do elementów poprzez indeksowanie listy. - Zalecanym sposobem w Pythonie jest użycie funkcji
enumerate()o składnienumerate(obiekt_iterowalny). Domyślnie indeksowanie zaczyna się od 0. - Możemy zdefiniować niestandardową wartość startową, używając składni
enumerate(obiekt_iterowalny, start), gdziestartjest początkowym indeksem. - Funkcja
enumeratemoże być stosowana do pracy z krotkami, napisami, słownikami i ogólnie z dowolnymi obiektami iterowalnymi.
Mam nadzieję, że ten tutorial był pomocny. W następnej kolejności zachęcam do zapoznania się z tematem wyszukiwania indeksów elementów w listach. Kontynuuj naukę!