Ten poradnik przedstawi Ci metody wyszukiwania pozycji elementu w strukturze danych jaką jest lista w Pythonie. Poznasz zarówno sposoby oparte na ręcznym iterowaniu, jak i wykorzystanie wbudowanej funkcji `index()`.
Podczas pracy z listami, często zachodzi potrzeba ustalenia, pod którym indeksem znajduje się dany element. Można to osiągnąć na dwa sposoby:
- Poprzez iterację po liście i weryfikację, czy element pod bieżącym indeksem odpowiada szukanej wartości.
- Używając wbudowanej metody `index()` dostępnej dla list.
W tym artykule omówimy oba podejścia. Zaczynajmy! 👩🏽💻
Listy w Pythonie – przypomnienie
W Pythonie lista to uporządkowany zbiór elementów, które mogą być tego samego lub różnych typów. Listy są modyfikowalne, co oznacza, że można je zmieniać bez konieczności tworzenia nowej listy.
Weźmy jako przykład listę owoców, składającą się z 5 różnych nazw:
fruits = ["apple","mango","strawberry","pomegranate","melon"]
Długość dowolnego obiektu w Pythonie można sprawdzić za pomocą funkcji `len()`. Wywołując `len()` z listą `fruits` jako argumentem, otrzymamy jej długość.
len(fruits) # Wynik: 5
W tym artykule będziemy bazować na liście owoców jako naszym przykładzie.
Indeksowanie w listach Pythona
Python stosuje indeksowanie od zera. To znaczy, że pierwszy element w liście ma indeks 0, drugi ma indeks 1 i tak dalej. Jeśli lista ma długość *k*, to ostatni element znajduje się pod indeksem *k* – 1.
Do generowania indeksów podczas iteracji po elementach w Pythonie można wykorzystać funkcję `range()`.
Warto pamiętać, że funkcja `range(k)` wygeneruje indeksy od 0 do *k* – 1. Zatem używając `range(len(lista))`, otrzymamy wszystkie poprawne indeksy listy.
Poniższy kod ilustruje to zagadnienie:
for i in range(len(fruits)): print(f"i:{i}, fruit[{i}] to {fruits[i]}") # Wynik i:0, fruit[0] to apple i:1, fruit[1] to mango i:2, fruit[2] to strawberry i:3, fruit[3] to pomegranate i:4, fruit[4] to melon
Teraz, gdy przypomnieliśmy sobie podstawy list w Pythonie, nauczmy się, jak wyszukać indeks konkretnego elementu.
Wyszukiwanie indeksu elementu listy poprzez iterację za pomocą pętli
Posłużmy się listą owoców z wcześniejszego przykładu. Zobaczymy, jak znaleźć indeks określonego elementu poprzez iterację przy pomocy pętli `for`.
Wykorzystanie pętli `for` i funkcji `range()`
Zdefiniujmy wartość, którą będziemy poszukiwać na liście.
Możemy wykorzystać pętlę `for` w połączeniu z `range()` do wygenerowania sekwencji indeksów od 0 do `len(fruits)` – 1.
- Iterujemy po liście `fruits`, uzyskując dostęp do każdego indeksu.
- Sprawdzamy, czy wartość pod danym indeksem `i` jest równa wartości docelowej.
- Jeśli warunek jest spełniony, wypisujemy komunikat informujący, że wartość została znaleziona pod indeksem `i`.
fruits = ["apple","mango","strawberry","pomegranate","melon"] target = "mango" for i in range(len(fruits)): if fruits[i] == target: print(f"{target} znaleziono pod indeksem {i}") # Wynik mango znaleziono pod indeksem 1
W tym przykładzie wartość „mango” występuje w liście tylko raz, pod indeksem 1.
Zdarza się, że szukana wartość występuje więcej niż jeden raz, lub wcale. Aby uwzględnić te przypadki, zmodyfikujemy kod i umieścimy go wewnątrz funkcji o nazwie `find_in_list`.
Analiza definicji funkcji
Funkcja `find_in_list` przyjmuje dwa parametry:
- `target`: wartość, której szukamy, oraz
- `py_list`: lista Pythona, którą przeszukujemy.
def find_in_list(target,py_list): target_indices = [] for i in range(len(fruits)): if fruits[i] == target: target_indices.append(i) if target_indices == []: print("Przykro mi, nie znaleziono celu!") else: print(f"{target} występuje pod indeksami: {target_indices}")
Wewnątrz funkcji inicjujemy pustą listę `target_indices`. Następnie iterujemy po liście, uzyskując dostęp do jej elementów. Jeśli wartość docelowa zostanie znaleziona pod danym indeksem, dodajemy ten indeks do listy `target_indices` za pomocą metody `append()`.
Warto wiedzieć, że metoda `list.append(element)` dodaje element na końcu listy.
- Jeśli szukana wartość nigdy nie zostanie odnaleziona, `target_indices` pozostaje pustą listą, a użytkownik zostanie o tym powiadomiony.
- Jeśli szukana wartość występuje pod wieloma indeksami, `target_indices` będzie zawierać wszystkie te indeksy.
Zmieńmy teraz listę owoców:
Szukamy teraz wartości „mango”, która występuje dwukrotnie, na indeksach 1 i 4.
fruits = ["apple","mango","strawberry","pomegranate","mango","melon"] target = "mango" find_in_list(target,fruits) # Wynik mango występuje pod indeksami: [1, 4]
Wywołując funkcję `find_in_list` z odpowiednimi argumentami, otrzymujemy listę z oboma indeksami.
target = "turnip" find_in_list(target,fruits) # Wynik Przykro mi, nie znaleziono celu!
Jeśli spróbujemy poszukać wartości „turnip” (rzepa), której nie ma na liście, zostanie wyświetlony komunikat o braku celu.
Wykorzystanie pętli `for` i funkcji `enumerate()`
W Pythonie możemy skorzystać z funkcji `enumerate()`, aby uzyskać dostęp zarówno do indeksu, jak i elementu w trakcie iteracji, bez potrzeby używania funkcji `range()`.
Poniższy przykład pokazuje, jak użyć funkcji `enumerate()` do uzyskania indeksu oraz elementu z listy.
fruits = ["apple","mango","strawberry","pomegranate","mango","melon"] for index,fruit in enumerate(fruits): print(f"Indeks {index}: {fruit}") # Wynik Indeks 0: apple Indeks 1: mango Indeks 2: strawberry Indeks 3: pomegranate Indeks 4: mango Indeks 5: melon
Przepiszmy teraz funkcję wyszukującą indeks, używając funkcji `enumerate()`.
def find_in_list(target,py_list): target_indices = [] for index, fruit in enumerate(fruits): if fruit == target: target_indices.append(index) if target_indices == []: print("Przykro mi, nie znaleziono celu!") else: print(f"{target} występuje pod indeksami: {target_indices}")
Tak samo jak w poprzednim przypadku, możemy teraz wywołać funkcję `find_in_list` z odpowiednimi argumentami.
Powyższą definicję funkcji można z łatwością przełożyć na równoważną listę składaną, co omówimy w następnej części.
Wyszukiwanie indeksu za pomocą list składanych
Listy składane w Pythonie umożliwiają tworzenie nowych list na podstawie już istniejących, w oparciu o określone warunki. Ogólna struktura listy składanej wygląda tak:
new_list = [<wyrażenie> for <element in kolekcja> if <warunek>]
Poniższa ilustracja przedstawia strukturę listy składanej; korzystając z niej możemy przekształcić naszą funkcję `find_in_list` na listę składaną.
Na podstawie powyższego, lista składana do utworzenia indeksów docelowych wygląda następująco:
target_indices = [index for index,fruit in enumerate(fruits) if fruit==target]
Zachęcamy do samodzielnego uruchomienia powyższego kodu z innymi przykładami.
Wyszukiwanie indeksu elementu za pomocą metody `index()`
Aby znaleźć indeks elementu w liście, możemy też wykorzystać wbudowaną metodę `.index()`. Jej ogólna składnia to:
list.index(wartość, start, end)
Analiza składni metody:
- `wartość` to szukana wartość docelowa.
- `start` i `end` to opcjonalne argumenty pozycyjne; można ich użyć do przeszukiwania wycinka listy od indeksu `start` do indeksu `end`-1.
Ważne: Metoda `.index()` zwraca tylko indeks pierwszego wystąpienia danej wartości w liście. Nawet jeśli szukamy indeksu w wycinku listy `[start:end-1]`, zwrócony zostanie tylko indeks pierwszego wystąpienia w tym wycinku.
Wróćmy do naszego przykładu, aby zrozumieć, jak działa metoda `.index()`.
fruits = ["apple","mango","strawberry","pomegranate","mango","melon"] target = "mango" fruits.index(target) 1
Chociaż „mango” występuje w liście dwukrotnie, zwrócony został indeks tylko pierwszego wystąpienia.
Aby uzyskać indeks drugiego wystąpienia, możemy przeszukać wycinek listy, zaczynając od indeksu 2 do 5, jak pokazano poniżej.
fruits.index(target,2,5) 4
Jak obsłużyć błędy `ValueError` w Pythonie?
Sprawdźmy teraz, co się stanie, gdy spróbujemy znaleźć element, którego nie ma na liście, np. „carrot” (marchewka).
target = "carrot" fruits.index(target) # Wynik --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-17-81bd454e44f7> in <module>() 1 target = "carrot" 2 ----> 3 fruits.index(target) ValueError: 'carrot' is not in list
Jak widać, powyższy kod generuje błąd ValueError. W Pythonie można obsłużyć ten wyjątek, wykorzystując bloki `try` i `except`.
Ogólna składnia bloku `try`-`except` wygląda następująco:
try: # kod, który może wywołać błąd except <TypBłędu>: # kod obsługujący błąd <TypBłędu>
Używając bloków `try`-`except` możemy obsłużyć `ValueError` jako wyjątek.
target = "carrot" try: fruits.index(target) except ValueError: print(f"Przykro mi, nie udało się znaleźć {target} na liście") # Wynik Przykro mi, nie udało się znaleźć carrot na liście
Powyższy kod wykonuje następujące operacje:
- Jeśli cel znajduje się na liście, zwraca jego indeks.
- Jeśli cel nie istnieje, przechwytuje błąd `ValueError` i wyświetla komunikat o błędzie.
Podsumowanie
Poniżej znajduje się podsumowanie różnych metod wyszukiwania indeksu elementu na liście w Pythonie, których się nauczyłeś.
- Możesz użyć pętli `for` i funkcji `range()` w Pythonie do uzyskania elementów i ich indeksów. Następnie należy sprawdzić, czy wartość pod danym indeksem pasuje do szukanego elementu.
- Możesz też użyć funkcji `enumerate()` do jednoczesnego uzyskania dostępu do elementu i indeksu.
- Obie powyższe metody można stosować wewnątrz wyrażeń list składanych.
- Do wyszukiwania indeksu elementu możesz wykorzystać wbudowaną metodę `.index()`.
- `list.index(wartość)` zwraca indeks pierwszego wystąpienia danej wartości na liście. Jeśli wartość nie jest obecna na liście, generowany jest błąd `ValueError`.
- Można przeszukiwać określony wycinek listy, używając `list.index(wartość, start, end)` w celu wyszukania wartości w wycinku `[start:end-1]`.
Teraz zachęcamy Cię do zgłębienia tematu sortowania słowników w Pythonie według klucza lub wartości. Miłego programowania w Pythonie!