Jak tworzyć krotki w Pythonie i dlaczego ich używać?

Krotki stanowią integralną część języka Python, będąc wbudowanym typem danych służącym do gromadzenia różnorodnych elementów. Choć przypominają listy, wyróżniają się większą szybkością działania.

Jednakże ich ograniczenia sprawiają, że w pewnych scenariuszach listy okazują się bardziej odpowiednie. W niniejszym artykule dogłębnie przeanalizujemy wszystkie aspekty krotek, aby umożliwić Ci efektywne korzystanie z nich.

Czym jest krotka?

Jak już wspomniano, krotka jest jednym z podstawowych typów danych w Pythonie, który służy do przechowywania zbiorów danych. Podobnie jak lista, przechowuje elementy w uporządkowanym formacie, przypominającym tablicę. Kluczową różnicą jest jednak to, że krotka jest *niezmienna*. Oznacza to, że po jej utworzeniu nie można modyfikować jej zawartości.

Nie można dodawać nowych elementów ani usuwać istniejących. Dlatego krotki doskonale nadają się do przechowywania danych, które mają pozostać stałe. Mogą obejmować zbiory elementów różnego typu. W dalszej części artykułu omówimy różne sposoby tworzenia krotek w Pythonie.

Sposoby tworzenia krotek w Pythonie

Istnieje kilka metod tworzenia krotek w Pythonie. W tej sekcji skupimy się na trzech najczęściej spotykanych i używanych sposobach, z którymi na pewno się zetkniesz, analizując kod innych programistów.

Aby uruchomić przykłady kodu przedstawione poniżej, upewnij się, że masz zainstalowanego Pythona. Jeśli jeszcze go nie masz, skorzystaj z dostępnych przewodników instalacji. Alternatywnie, możesz użyć internetowego środowiska Python, takiego jak Google Colab.

# 1. Użycie literału krotki (nawiasy)

Najbardziej rozpowszechnioną metodą definiowania krotek w Pythonie jest umieszczenie zbioru wartości w nawiasach okrągłych. Poszczególne elementy oddzielamy przecinkami. Poniższy przykład ilustruje tę technikę:

# Tworzenie krotki poprzez umieszczenie wartości w nawiasach
values = (1, 2, 3)

# Wyświetlenie krotki na ekranie
print(values)

# Wyświetlenie typu zmiennej values
print(type(values))

Powyższy kod wygeneruje następujące wyjście:

Jak widać, krotka zawiera dokładnie te wartości, którymi ją zainicjowaliśmy. Ponadto jej typem jest .

W Pythonie nawiasy okrągłe nie są obligatoryjne przy tworzeniu krotek. Oznacza to, że zapis `values = 1, 2, 3` jest równoważny `values = (1, 2, 3)`. Niemniej jednak, używanie nawiasów jest zalecane, ponieważ zwiększa czytelność kodu.

Tworzenie krotek z jednym elementem w Pythonie wymaga pewnej ostrożności. Nie wystarczy umieścić pojedynczy element w nawiasach; należy również dodać przecinek na końcu. Poniższy przykład ilustruje to zagadnienie:

# Bez przecinka na końcu, to nie utworzy krotki
not_a_tuple = (1)

# Z przecinkiem na końcu, utworzy krotkę
a_tuple = (1,)

# Wyświetlenie not_a_tuple
print(not_a_tuple)

# Wyświetlenie typu danych not_a_tuple
print(type(not_a_tuple))

# Wyświetlenie a_tuple
print(a_tuple)

# Wyświetlenie typu danych a_tuple
print(type(a_tuple))

Po uruchomieniu powyższego kodu przekonasz się, że `not_a_tuple` staje się liczbą całkowitą o wartości 1. Pamiętaj o tym podczas tworzenia krotek.

#2. Użycie funkcji konstruktora

Druga metoda tworzenia krotek w Pythonie wykorzystuje funkcję konstruktora `tuple()`. W tej technice wywołujemy funkcję, przekazując jako argument obiekt iterowalny, taki jak lista. Funkcja ta przekształci dany obiekt w krotkę. Oto przykład:

# Tworzenie krotki z listy wartości
values = tuple([1, 2, 3])

# Wyświetlenie wartości
print(values)

# Wyświetlenie typu danych zmiennej values
print(type(values))

Jak widać, wynik użycia funkcji jest identyczny z wynikiem użycia literału. Niemniej jednak, funkcja ta pozwala na utworzenie krotki na podstawie wartości, która jest dynamiczna, jak na przykład lista, której wartości są znane dopiero podczas wykonywania programu. W przypadku pierwszej metody, wartości lub identyfikatory tworzące krotkę musiałyby być znane w momencie pisania kodu.

#3. Tworzenie pustej krotki

Podczas pracy z krotkami w kodzie może zaistnieć potrzeba utworzenia pustych krotek. Puste krotki tworzymy w intuicyjny sposób. Możemy do tego celu użyć konstruktora `tuple()` lub literału. Oto przykład zastosowania obu metod:

# Użycie literału krotki
empty_tuple_1 = ()

# Użycie konstruktora
empty_tuple_2 = tuple()

Puste krotki okazują się użyteczne w sytuacjach, gdy reprezentują pusty zbiór wyników. Rozważmy następującą funkcję:

def create_range(start, end):
    return tuple(range(start, end))

Ta funkcja tworzy krotkę z wartościami w określonym zakresie. Chcąc przejść po wynikach funkcji, moglibyśmy użyć czegoś takiego:

my_values = create_range(0, 5)

for value in my_values:
    pass

Jeśli przekazalibyśmy do funkcji `create_range` wartości 5 i 5, wynikiem byłaby pusta krotka. W takim przypadku, próba iteracji nie spowodowałaby żadnego błędu, a kod zadziałałby bez zakłóceń.

Z drugiej strony, gdyby puste krotki nie istniały, a funkcja zwracałaby na przykład wartość `None`, to próba iteracji po niej wywołałaby błąd. Aby zapobiec awariom programu, musielibyśmy dodać dodatkowy warunek obsługujący przypadek, w którym funkcja `create_range` zwraca `None` lub inną wartość reprezentującą pustą krotkę.

Prowadziłoby to do nieczytelnego kodu. W idealnym scenariuszu, powinniśmy unikać szczególnych przypadków tak bardzo, jak to możliwe. Oznacza to, że wartości zwracane przez wszystkie funkcje powinny mieć identyczny interfejs, aby kod był jak najbardziej uniwersalny. W tym konkretnym przypadku oznacza to ciągłe zwracanie krotki, nawet jeśli czasami będzie ona pusta.

Sposoby uzyskiwania dostępu do elementów

Istnieją dwie główne metody dostępu do elementów krotki w Pythonie. Pierwsza metoda polega na indeksowaniu, a druga na rozpakowywaniu elementów. Najpierw zbadamy, jak uzyskać dostęp do elementów za pomocą indeksów.

Dostęp do elementów za pomocą indeksu

Dostęp do elementów za pomocą indeksu jest analogiczny do uzyskiwania dostępu do elementów listy. Robimy to za pomocą notacji nawiasów kwadratowych. Krotki, tak jak listy, używają systemu indeksowania od zera. Oznacza to, że pierwszy element ma indeks 0, drugi 1 i tak dalej, aż do ostatniego elementu.

Poniższy przykład ilustruje, jak uzyskać dostęp do elementów za pomocą indeksu:

# Tworzenie krotki
values = (1, 2, 3, 4)

# Dostęp do pierwszego elementu
first_element = values[0]

# Dostęp do czwartego elementu (indeks 3)
fourth_element = values[3]

Możemy również użyć indeksowania ujemnego. Element o indeksie -1 to ostatni element, a element o indeksie -2 to przedostatni element.

# Tworzenie krotki
values = (1, 2, 3, 4)

# Dostęp do ostatniego elementu
last_element = values[-1]

# Dostęp do przedostatniego elementu
second_from_last_element = values[-2] 

Ponadto, możemy wyodrębnić fragmenty krotki, stosując mechanizm wycinania (slicing). Jest to analogiczne do sposobu wycinania list. Notacja ma postać: `[ : : ]`. Poniższy przykład ilustruje działanie tej techniki:

# Tworzenie krotki
values = (1, 2, 3, 4, 5, 6, 7)

# Pobieranie pierwszych trzech elementów
values[1: 3]

# Pobieranie co drugiego elementu
values[::2]

Iteracja po elementach

Krotka jest obiektem iterowalnym w Pythonie. Dlatego możemy iterować po jej elementach za pomocą pętli `for`, jak w poniższym przykładzie:

values = (1, 2, 3, 4)

for value in values:
    print(value)

Ta metoda dostępu do elementów idealnie sprawdza się w sytuacji, gdy chcemy przeanalizować wszystkie elementy krotki.

Dostęp do elementów poprzez rozpakowywanie (destrukturyzację)

Aby wyjaśnić mechanizm rozpakowywania, rozważmy sytuację, w której próbujemy uzyskać dostęp do różnych elementów krotki.

# Tworzenie krotki z informacjami o użytkowniku
person_record = (1, 'Jan Kowalski', '[email protected]')

# Dostęp do poszczególnych elementów krotki
id = person_record[0]
name = person_record[1]
email = person_record[2]

Python oferuje bardziej elegancką i wygodną metodę dostępu do wartości, jak pokazano poniżej:

# Tworzenie krotki z informacjami o użytkowniku
person_record = (1, 'Jan Kowalski', '[email protected]')

id, name, email = person_record

Ta operacja nazywa się *rozpakowywaniem*. Oznacza to, że pierwszej zmiennej, w tym przypadku `id`, zostanie przypisana pierwsza wartość w krotce, drugiej zmiennej – drugi element, i tak dalej aż do końca krotki. Powyższy przykład jest ekwiwalentny następującemu zapisowi:

id, name, email = (1, 'Jan Kowalski', '[email protected]')

W tym przypadku, zamiast przechowywać krotkę w zmiennej, natychmiast ją rozpakowujemy. Biorąc pod uwagę fakt, że nawiasy nie są wymagane podczas tworzenia krotek, kod można zapisać jeszcze zwięźlej:

id, name, email = 1, 'Jan Kowalski', '[email protected]'

W rezultacie otrzymamy zmienne `id`, `name` i `email` o wartościach odpowiednio: 1, „Jan Kowalski” i „[email protected]„. Jest to wygodny i zwięzły sposób definiowania zmiennych w Pythonie, który często spotykany jest w kodzie produkcyjnym. Warto zapamiętać, że u podstaw tej eleganckiej składni leży koncepcja krotek.

Różnice między krotką a listą

Choć krotki i listy są do siebie podobne, istnieją kluczowe różnice, które sprawiają, że każdy z tych typów danych jest bardziej odpowiedni do określonego zastosowania. Zrozumienie tych różnic pomoże Ci w wyborze najbardziej odpowiedniej struktury danych i umożliwi pisanie lepszego i bardziej wydajnego kodu.

Aspekt Krotka Lista
Pamięć Przechowywane w ciągłym bloku pamięci Przechowywane w różnych, niekoniecznie sąsiadujących fragmentach pamięci
Zmienność Niezmienne (nie można modyfikować po utworzeniu) Zmienne (można modyfikować po utworzeniu)
Szybkość Dostęp do elementów jest szybszy Dostęp do elementów jest wolniejszy
Typ danych Zazwyczaj przechowuje elementy różnych typów Zazwyczaj przechowuje elementy tego samego typu
Zastosowanie Przechowywanie kolekcji o stałej strukturze, często z elementami różnych typów Przechowywanie kolekcji zmiennych elementów, najczęściej tego samego typu

Zalety krotki

# 1. Szybkość działania

Ze względu na sposób przechowywania wartości (w ciągłym bloku pamięci), dostęp do elementów krotki jest szybszy niż w przypadku listy. Jednak ze względu na to, że nie można ich modyfikować po utworzeniu, krotki nie zawsze stanowią optymalną strukturę danych do przechowywania zbioru wartości.

Idealnym zastosowaniem krotek jest przechowywanie dużych ilości danych, które nie ulegają zmianom, a które są często wykorzystywane podczas wykonywania programu. W takiej sytuacji program może znacznie skorzystać z wyższej wydajności krotek.

#2. Zwracanie wielu wartości

Krotki można wykorzystać do zwracania wielu wartości z funkcji i rozpakowania rezultatu. Na przykład:

from random import randint

def create_two_numbers():
    first_num = randint(0, 9)
    second_num = randint(0, 9)

    return first_num, second_num

first_num, second_num = create_two_numbers()

W tym przykładzie, funkcja generuje dwie losowe liczby i zwraca je obie w krotce. Zapis `return first_num, second_num` jest tożsamy z zapisem `return (first_num, second_num)`. Dzieje się tak, ponieważ nawiasy nie są obowiązkowe podczas definiowania krotek. Aby uzyskać dostęp do wyniku, rozpakowujemy krotkę.

#3. Ochrona wartości przed zapisem

Krotki są niezmienne po utworzeniu. Dlatego idealnie nadają się do przechowywania danych, które nie ulegają zmianom podczas działania programu. Zapewniają, że dane nie zostaną przypadkowo nadpisane w innej części kodu.

#4. Przechowywanie różnych typów danych

Krotki pozwalają na przechowywanie wartości różnych typów. Dzięki temu możemy tworzyć struktury danych, na przykład zapisywanie danych użytkownika w krotce. Można również przechowywać bardziej skomplikowane elementy, takie jak funkcje, słowniki, inne krotki, a nawet listy.

Najczęściej używane metody krotek

# 1. `count()`

Obiekt krotki posiada metodę `count()`, która zwraca liczbę wystąpień danego elementu. Na przykład:

# Tworzenie krotki z kilkoma liczbami
values = (1, 2, 3, 4, 5, 4, 4, 6)

# Zliczanie liczby czwórek
n_fours = values.count(4)

# Wyświetlenie liczby czwórek
print(n_fours)

Z tego przykładu wynika, że liczba 4 pojawia się w naszej krotce dokładnie trzy razy.

#2. `index()`

Metoda `index()` pozwala na znalezienie indeksu pierwszego wystąpienia danej wartości w krotce. Jeśli wartość nie istnieje, zgłoszony zostanie wyjątek `ValueError`. Poniżej przedstawiono kod, który ilustruje działanie metody `index()`:

# Tworzenie krotki z kilkoma liczbami
values = (1, 2, 3, 4, 5, 4, 4, 6)

# Wyszukiwanie indeksu liczby 4
index_of_four = values.index(4)
print("Indeks liczby 4:", index_of_four)

# Wyszukiwanie indeksu liczby 9
index_of_nine = values.index(9)
print("Indeks liczby 9:", index_of_nine)

Po uruchomieniu powyższego kodu otrzymamy następujące wyjście:

W tym przypadku indeks liczby 4 wynosi 3, a kod działał bezproblemowo. Jednak w sytuacji, gdy próbowaliśmy znaleźć indeks liczby 9, program zgłosił wyjątek. Bardzo ważne jest, aby odpowiednio obsługiwać wyjątki podczas pisania programów w Pythonie, które korzystają z metody `index()`.

#3. `len()`

Podobnie jak wszystkie obiekty iterowalne w Pythonie, krotki mają właściwość długości, do której możemy uzyskać dostęp, przekazując krotkę jako argument do funkcji `len()`.

# Tworzenie krotki
values = (1, 2, 3, 4)

# Pobieranie długości krotki
length = len(values)

# Wyświetlenie długości krotki
print(length)

Powyżej przedstawiony został wynik uruchomienia kodu.

#4. `min()` i `max()`

Metody `min()` i `max()` iterują po każdym elemencie w zbiorze i porównują go z poprzednim elementem w celu ustalenia, który z nich jest większy/mniejszy. Na końcu `max()` zwróci największy element, a `min()` najmniejszy.

W przypadku liczb, działanie obu metod jest intuicyjne. W przypadku łańcuchów tekstowych, Python używa porządku alfabetycznego. Słowo zwracane przez `min()` będzie pierwszym słowem w porządku alfabetycznym, natomiast słowo zwracane przez `max()` będzie ostatnim. Jeśli zbiór danych zawiera elementy różnych typów, obie operacje zakończą się niepowodzeniem, ponieważ Python nie będzie wiedział, jak porównywać elementy różnych typów.

Poniżej przedstawiony został przykład kodu:

# Tworzenie krotki z wartościami
values = (1, 2, 3, 4, 5)

# Pobieranie największej wartości
largest = max(values)

# Pobieranie najmniejszej wartości
smallest = min(values)

# Wyświetlenie wyników
print(largest)
print(smallest)

#5. `sorted()`

Funkcja `sorted()` w Pythonie przyjmuje obiekt iterowalny i zwraca listę posortowanych elementów. Możemy wywołać funkcję `sorted()`, przekazując krotkę jako argument, a otrzymamy listę posortowanych elementów. Aby przekonwertować posortowaną listę na krotkę, możemy użyć funkcji konstruktora. Poniżej zaprezentowano przykład:

# Tworzenie krotki z wartościami w losowej kolejności
values = (1, 5, 3, 3, 2, 4)

# Użycie sorted() do posortowania wartości i zapisania ich na liście
sorted_list = sorted(values)

# Konwersja listy na krotkę
sorted_tuple = tuple(sorted_list)

# Wyświetlenie wyniku
print(sorted_tuple)

#6. Dodawanie i mnożenie krotek

Operacja dodawania dwóch krotek łączy je w jedną. Operacja mnożenia powtarza elementy krotki określoną liczbę razy. Poniżej przedstawiono przykład, który ilustruje obie te operacje.

# Tworzenie krotki z kilkoma wartościami
values = (1, 2, 3, 4, 5)

# Tworzenie nowej krotki za pomocą dodawania
added = values + values

# Tworzenie nowej krotki za pomocą mnożenia
multiplied = values * 2

print("values + values =", added)
print("values * 2 =", multiplied)

Podsumowanie

W tym artykule dowiedzieliśmy się, że:

  • Krotki są obiektami przypominającymi listy, używanymi do przechowywania kolekcji wartości.
  • W przeciwieństwie do list, są one niezmienne.
  • Są szybsze i wydajniejsze niż listy.
  • Można je tworzyć, umieszczając wartości w nawiasach i oddzielając je przecinkami.
  • Można je również tworzyć za pomocą funkcji konstruktora krotek.
  • Dostęp do poszczególnych elementów można uzyskać za pomocą systemu indeksowania od zera.
  • Możemy również rozpakowywać wartości z krotki.
  • Możemy również iterować po wartościach za pomocą pętli `for`.
  • Istnieje szereg metod, które możemy stosować z krotkami.

W kolejnych krokach zachęcamy Cię do zapoznania się z innymi materiałami dotyczącymi Pythona, takimi jak omówienie metod list i słowników w Pythonie.


newsblog.pl