Struktury danych
Pomagają przechowywać, porządkować i przetwarzać dane.
Jest ich wiele rodzajów - wybór struktury danych zależy od tego co chcemy osiągnąć, co ma robić nasz program i do czego ma służyć. Dlatego wybór struktury danych dobrze jest zacząć od zastanowienia się co dokładnie nasz program ma robić, do czego ma służyć, które dane nie będą się zmieniać, a które być może tak itp. i dopiero potem dopasować do tego odpowiednią strukturę. Dzięki temu unikniemy sytuacji, w której po wielu godzinach pracy okaże się, że dalej nie możemy iść z powodu złego wyboru na początku.
Listy (list) i krotki (tuple)
Są do siebie podobne pod pewnymi względami:
- każdy element ma swój indeks, który umożliwia jego szybkie odnalezienie (WAŻNE: numery indeksów zaczynają się od 0, a nie od 1, zatem pierwszy element listy czy krotki ma indeks 0, a drugi 1 itd.)
- mogą posiadać duplikaty
- można się przemieszczać (iterate) po ich elementach
Mają też jednak istotne różnice:
LISTY
- są modyfikowalne (mutable), więc można do nich dodawać czy odejmować nowe elementy, można też zmieniać istniejące elementy
- bardzo często przemieszczamy się po ich elementach
- unika się sięgania po elementy ze środka listy
- deklaruje się je w nawiasach kwadratowych []
numery_indeksow = ["zero", "jeden", "dwa", "trzy"]
KROTKI
- nie są modyfikowalne (immutable)
- mają stałą długość - łatwo jest sięgnąć po elementy ze środka, umieszczone głęboko
- deklaruje się je w nawiasach okrągłych ()
kraje_oscienne = ("Niemcy", "Litwa", "Czechy", "Rosja", "Słowacja", "Białoruś", "Ukraina")
💡Jeśli chcemy wyciągnąć dany element listy czy krotki zapisujemy indeks w nawiasach kwadratowych. Jeśli chcemy wyciągnąć jakiś element od końca listy/krotki to używamy liczb ujemnych -> wtedy numery idą "normalnie" tzn. -1 oznacza pierwszy indeks od końca, -2 drugi itd.
print(numery_indeksow[1]) # odpowiedź programu -> jeden
print(numery_indeksow[-1]) # odpowiedź programu -> trzy
print(kraje_oscienne[4]) # odpowiedź programu -> Słowacja
print(kraje_oscienne[-2]) # odpowiedź programu -> Białoruś
💡Jeśli chcemy wyciągnąć zakres elementów listy czy krotki należy w nawiasie kwadratowym wpisać element startowy i końcowy oddzielone dwukropkiem -> WAŻNE - element startowy się wyświetli jako pierwszy, ale element końcowy to informacja przed którym indeksem się zakończy wyświetlanie, tzn. element końcowy się nie wyświetli, ale wyświetli się jeden wcześniej.
Jeśli chcemy wyświetlić od danego elementu do ostatniego to po numerze pierwszego indeksu zostawiamy tylko dwukropek, a jeśli chcemy wyświetlać elementy od końca to używamy liczb ujemnych. Można też wyświetlać co któryś element od danego indeksu, wtedy stosujemy dwa dwukropki po numerze indeksu i po dwukropkach definiujemy co który indeks ma się wyświetlić:
print(kraje_oscienne[0:4]) # odpowiedź programu -> ('Niemcy', 'Litwa', 'Czechy', 'Rosja')
print(kraje_oscienne[5:]) # odpowiedź programu -> ('Białoruś', 'Ukraina')
print(numery_indeksow[-2:]) # odpowiedź programu -> ['dwa', 'trzy']
print(numery_indeksow[0::2]) # odpowiedź programu -> ['zero', 'dwa']
METODY DLA LIST I KROTEK
Metody to specjalne funkcje "wbudowane" w dany obiekt. Używa się ich przez wpisanie nazwy zmiennej, postawienie kropki i wstawienie parametrów do metody w nawiasach okrągłych (nawiasy mogą zostać puste, jeśli nie mamy żadnych parametrów, ale muszą być!)
Dla krotek jest ich mniej, bo krotki są niemodyfikowalne.
Metoda | Dla list ✅ | Dla krotek ✅ | Opis działania |
---|---|---|---|
append(x) |
✅ | ❌ | Dodaje element x na koniec listy |
insert(i, x) |
✅ | ❌ | Wstawia x na pozycję i |
extend(l) |
✅ | ❌ | Rozszerza listę o elementy z innej listy |
remove(x) |
✅ | ❌ | Usuwa pierwsze wystąpienie x |
pop(i) |
✅ | ❌ | Usuwa i zwraca element z pozycji i |
clear() |
✅ | ❌ | Usuwa wszystkie elementy z listy |
sort() |
✅ | ❌ | Sortuje elementy listy |
reverse() |
✅ | ❌ | Odwraca kolejność elementów |
copy() |
✅ | ❌ | Zwraca kopię listy |
count(x) |
✅ | ✅ | Zlicza, ile razy x występuje |
index(x) |
✅ | ✅ | Zwraca indeks pierwszego wystąpienia x |
Słowniki (dict) i zbiory (set)
Słowniki i zbiory przechowują klucze, a w przypadku słowników dodatkowo do kluczy przypisane są wartości
Klucze muszą być wartością na której da się wykonać tzw. funkcję skrótu (są "hashable"). W tym wypadku chodzi o to, że muszą to być obiekty, które nie są modyfikowalne (np. ciągi znaków, liczby). Jeśli klucz mógłby się zmienić – jego hash by się zmienił – i system nie znalazłby go na nowo.
SŁOWNIKI
Słowniki to kolekcja par klucz:wartość - umożliwiają szybkie odnalezienie wartości za pomocą klucza przypisanego do niej. Deklarujemy je nawiasami klamrowymi, w których znajdują się pary klucz:wartość oddzielone dwukropkiem.
siostra = {
"imię": "Ala",
"wiek": 25,
"miasto": "Warszawa"
}
Jeśli chcemy wywołać wartość przypisaną do klucza to postępujemy podobnie jak w przypadku list i krotek, ale w nawiasie kwadratowym zamiast indeksu wpisujemy klucz
print(siostra["wiek"]) # odpowiedź programu -> 25
🔑 Cechy słownika
- Klucze są unikalne (nie mogą się powtarzać) - przy ponownym przypisaniu wartości do tego samego klucza stara wartość zostanie zastąpiona nową
- Klucze mogą być np. tekstem, liczbą, ale muszą być niemodyfikowalne - lista odpada
- Wartości mogą być dowolne (liczby, teksty, listy itd.), ale warto być konsekwentnym i nie mieszać tekstów z liczbami, krotkami itp.
- Wartości mogą się powtarzać
Najważniejsze metody słownika
Metoda | Opis |
---|---|
get(klucz) | Zwraca wartość dla danego klucza (bez błędu przy braku) |
keys() | Zwraca listę kluczy |
values() | Zwraca listę wartości |
items() | Zwraca listę par (klucz, wartość) |
update() | Aktualizuje słownik |
pop(klucz) | Usuwa element o danym kluczu |
clear() | Usuwa wszystko |
ZBIORY
Kolekcje unikalnych elementów, są podobne do listy, ale nie mogą posiadać duplikatów wartości (jeśli spróbujemy dodać drugi raz tę samą wartość to zostanie ona usunięta)
⭐️Cechy zbioru:
- Nie ma duplikatów
- Nie ma indeksów (nie można np.
owoce[0]
) - Porządku nie da się przewidzieć
- Takie jakby słowniki, ale z samymi kluczami
- Podobnie jak słowniki, deklarujemy je nawiasami klamrowymi
Zbiory są przydatne, kiedy np. chcemy usunąć duplikaty - wystarczy zamienić np. listę na zbiór
owoce = {"jabłko", "banan", "gruszka", "śliwka"}
# Sprawdzenie, czy "banan" jest w zbiorze
if "banan" in owoce:
print("Zbiór zawiera banana!")
else:
print("Nie ma banana!")
# odpowiedz programu -> Zbiór zawiera banana!
Najważniejsze metody zbioru
Metoda | Opis |
---|---|
add(x) | Dodaje element |
remove(x) | Usuwa element (błąd jeśli go nie ma) |
discard(x) | Usuwa element (bez błędu) |
clear() | Czyści zbiór |
union() | Suma zbiorów (łączy zbiory) |
intersection() | Część wspólna zbiorów |
difference() | Różnica zbiorów |