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.).start
to opcjonalny parametr określający, od jakiej wartości ma zacząć się indeksowanie. Domyślniestart
wynosi 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
for
pozwala 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)
, gdziestart
jest początkowym indeksem. - Funkcja
enumerate
moż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ę!