Prednáška 2: Dátové štruktúry v Pythone¶
V prvej prednáške sme si povedali o základných dátových typoch (číselné, reťazce, boolovské hodnoty) a prebrali sme si aj princípy Jupyter Notebooku, funkcie print
, premenné a pod. Teraz sa pozrieme na komplexnejšie dátové štruktúry (kolekcie) a ďalej spomenieme aj prácu s dátumom a časom.
Obsah¶
- Zoznamy (lists)
- Vytvorenie
- Indexovanie, záporné indexy
- Úpravy prvkov, pridávanie, mazanie, spájanie
- Kopírovanie, rozsahy (slicing), vnorené zoznamy
- Ďalšie metódy
- Prehľad a praktické tipy
- N-tice (tuples)
- Vytvorenie, prístup k prvkom
- Nemennosť
- Rozbaľovanie (unpacking)
- Jednoprvkové n-tice
- Množiny (sets)
- Vytvorenie, vlastnosti, použitie
- Bežné metódy (add, remove, in, len)
- Množinové operácie (zjednotenie, prienik, rozdiel)
- Prehľad a využitie
- Slovníky (dictionaries)
- Vytvorenie, prístup k hodnotám
- Pridávanie, mazanie, kľúče a ich obmedzenia
- Metódy keys(), values(), items()
- Špeciálne metódy (get, pop)
- Iterácia a využitie v praxi
- Dátum a čas (datetime)
- Načítanie modulu
- Vytváranie objektov time, datetime
- Atribúty (hour, minute, year, month, …)
- Metódy now(), strftime(), strptime()
- Formátovacie kódy
- Pokročilé tipy a doplnky
- Shallow vs. deep copy (krátka zmienka)
- List/Set/Dict comprehensions (krátky úvod)
- Ďalšie užitočné moduly a knižnice (napr.
collections
)
1. Zoznamy (Lists)¶
Základné vlastnosti¶
- Zoznam je usporiadaná postupnosť prvkov, ku ktorým vieme pristupovať podľa indexu (
0, 1, 2, …
). - Mutovateľná štruktúra – môžeme meniť hodnoty jednotlivých prvkov aj po vytvorení zoznamu.
- Môže obsahovať ľubovoľné typy (reťazce, čísla, bool, iné zoznamy…).
Vytvorenie¶
numbers = [1, 2, 3, 4] # zoznam s 4 prvkami
mixed = ["hello", 10, True, 3.14] # rôzne typy
empty = [] # prázdny zoznam
numbers2 = list((1, 2, 3)) # vytvorenie cez konštruktor list
numbers2
Prístup k prvkom a indexovanie¶
print(numbers[0]) # prvý prvok => 1
print(numbers[-1]) # posledný prvok => 4
numbers[1] = 100 # zmena druhého prvku na 100
print(numbers) # [1, 100, 3, 4]
Záporné indexy rátajú od konca (-1
= posledný, -2
= predposledný…).
Rozsahy (slicing)¶
Podobne ako pri reťazcoch môžeme použiť syntax list[od:do]
(aj s možnosťou krok
).
numbers = [0, 1, 2, 3, 4, 5]
print(numbers[2:5]) # prvky s indexom 2,3,4 => [2, 3, 4]
print(numbers[:3]) # prvky s indexom 0,1,2 => [0, 1, 2]
print(numbers[ : :2]) # každý druhý prvok => [0, 2, 4]
# Zaujímavosť: priamo môžeme nahradiť rozsah inými prvkami
numbers[1:3] = ["one", "two"] # nahradí indexy 1 a 2
print(numbers) # [0, 'one', 'two', 3, 4, 5]
# Vymazanie posledných 2 prvkov:
numbers[-2:] = []
print(numbers) # [0, 'one', 'two', 3]
# Celé vyčistenie:
numbers[:] = []
print(numbers) # []
Pridávanie a mazanie¶
list.append(x)
– pridá prvokx
na konieclist.insert(i, x)
– vloží prvokx
na pozíciui
list.pop(i)
– vráti a odstráni prvok na indexei
(aki
neuvedieme, odstráni posledný)list.remove(x)
– vyhľadá prvý výskytx
a odstráni hodel list[i]
– odstráni prvok na indexei
numbers = [1, 2, 3]
numbers.append([5]) # pridá 5 na koniec
print(numbers) # [1, 2, 3, 5]
numbers.insert(1, 10) # vloží 10 na index 1
print(numbers) # [1, 10, 2, 3, 5]
numbers.remove(10) # odstráni prvý výskyt 10
print(numbers) # [1, 2, 3, 5]
popped = numbers.pop() # vyberie a odstráni posledný prvok
print(popped) # 5
print(numbers) # [1, 2, 3]
del numbers[0] # odstráni prvok na indexe 0
print(numbers) # [2, 3]
Ďalšie bežné operácie¶
list1 + list2
(spojenie zoznamov)list * n
(opakované zreťazenie)x in list
(test členstva)len(list)
(počet prvkov)list.sort()
(zoradenie prvkov – mení pôvodný zoznam)sorted(list)
(vráti nový usporiadaný zoznam, pôvodný nemení)list.reverse()
(otočí poradie prvkov – mení pôvodný zoznam)
list1 = [1, 2]
list2 = [3, 4]
spojenie = list1 + list2 # spojenie
print(spojenie) # [1, 2, 3, 4]
opak = list1 * 3 # [1, 2, 1, 2, 1, 2]
print(opak)
print(2 in list1) # True
print(len(list1)) # 2
list3 = [2, 1, 4, 3]
list3.sort() # mení pôvodný zoznam
print(list3) # [1, 2, 3, 4]
list3.reverse()
print(list3) # [4, 3, 2, 1]
list4 = [2, 1, 4, 3]
sorted_list4 = sorted(list4) # vráti nový usporiadaný zoznam
print(sorted_list4) # [1, 2, 3, 4]
print(list4) # [2, 1, 4, 3] (pôvodný ostáva)
Vnorené zoznamy¶
Zoznam môže obsahovať iné zoznamy alebo iné kolekcie:
matrix = [
[1, 2, 3],
[4, 5, 6]
]
print(matrix[0][1]) # 2
print(matrix[1][2]) # 6
Kopírovanie¶
Zoznam kopírujeme najčastejšie:
old_list = [1, 2, [3, 4]]
new_list = old_list[:] # slicing
another_copy = list(old_list) # konštruktor
print(new_list)
print(another_copy)
# POZOR na vnorené štruktúry (shallow copy)
old_list[2][0] = 'X'
print(old_list) # [1, 2, ['X', 4]]
print(new_list) # [1, 2, ['X', 4]] (vnorený list zdieľa referenciu)
print(another_copy)
2. N-tice (Tuples)¶
- N-tica je nemenná postupnosť.
- Dá sa indexovať (t[0], t[1], …), ale nedajú sa meniť prvky po vytvorení.
- Používa sa často na balenie menšieho počtu logicky spojených hodnôt.
Vytvorenie n-tice¶
t = (1, 2, 3)
t2 = tuple([4, 5, 6])
print(t[1]) # 2
# jednoprvková n-tica
single = (5,)
print(single) # (5,)
Jednoprvková n-tica: (5,) – treba čiarku, inak je to len obyčajná zátvorka.
Rozbaľovanie (unpacking)¶
Počet premenných sa musí presne rovnať dĺžke n-tice.
coords = (10, 20)
x, y = coords
print(x) # 10
print(y) # 20
Prečo použiť n-ticu?¶
- Chceme vyjadriť, že tento „zoznam“ sa nemá meniť.
- Často pri vrátení viacerých hodnôt z funkcie (napr.
return (result, error_code)
).
3. Množiny (Sets)¶
- Množina (set) je neusporiadaná kolekcia jedinečných prvkov.
- Duplicitné hodnoty sa ukladajú iba raz.
- Veľmi rýchle testovanie členstva (x in s).
Vytvorenie¶
fruits_list = ["apple", "orange", "apple", "banana"]
fruits_set = set(fruits_list)
print(fruits_set) # napr. {'banana', 'apple', 'orange'}
empty_set = set()
Metódy a operácie¶
s.add(x)
– pridáx
do množiny (ak tam už je, nič sa nezmení)s.remove(x)
– akx
neexistuje, dostanemeKeyError
len(s)
– počet prvkovx in s
– test členstva
s = {1,2,3}
s.add(3) # pridanie duplicitnej hodnoty sa neprejaví
print(s) # {1,2,3}
s.remove(2) # odstráni '2'
print(s) # {1,3}
print(1 in s) # True
print(len(s)) # 2
Množinové operácie¶
a | b
: zjednotenie (prvky, čo sú va
alebo vb
)a & b
: prienik (prvky, čo sú va
aj vb
)a - b
: rozdiel (prvky, čo sú va
, ale nie sú vb
)
a = set([1, 2, 3])
b = set([2, 3, 4])
print(a | b) # zjednotenie => {1, 2, 3, 4}
print(a & b) # prienik => {2, 3}
print(a - b) # rozdiel => {1}
Praktické využitie¶
- Odstránenie duplicitných hodnôt z listu (napr. zoznam mailov, atď.).
- Kontrola, či sa niečo vyskytuje (členstvo v set) – oveľa rýchlejšie ako
list
.
4. Slovníky (Dictionaries)¶
- Slovník (dict) je neusporiadaná kolekcia kľúč : hodnota (key–value).
- Každý kľúč sa môže v slovníku vyskytnúť iba raz.
- Kľúč môže byť reťazec, číslo, bool či n-tica (nemenná). Hodnota môže byť čokoľvek.
Vytvorenie¶
Ak kľúč neexistuje, tel["peter"]
vyhodí KeyError
.
tel = {
"jack": 1234,
"john": 2345
}
print(tel["jack"]) # 1234
# chýbajúci kľúč => KeyError
# print(tel["peter"]) # KeyError
Pridávanie a mazanie¶
Ak john
neexistuje, KeyError
.
tel["hannah"] = 9999
print(tel)
tel["jack"] = 5555 # prepíšeme
print(tel)
del tel["john"]
print(tel)
Metódy a vlastnosti¶
len(dict)
– počet kľúčov"hannah" in tel
– vrátiTrue
, ak kľúč"hannah"
existujetel.keys()
– vráti všetky kľúče (v podobe tzv.dict_keys
– iterovateľné)tel.values()
– vráti všetky hodnotytel.items()
– vráti páry(kľúč, hodnota)
tel.get(key, default)
– vráti hodnotu, alebodefault
ak kľúč neexistujetel.pop(key, default)
– vyberie a vymaže kľúč, vráti jeho hodnotu, inakdefault
print(len(tel)) # počet kľúčov
print("hannah" in tel) # True/False
print(tel.keys()) # dict_keys([...])
print(tel.values())
print(tel.items()) # páry (kľúč, hodnota)
print(tel.get("unknown", "nie je tam")) # nevyhodí chybu, ak neexistuje
# pop:
val = tel.pop("hannah", None)
print(val) # vybral 9999
print(tel) # hannah už neexistuje
Iterácia cez slovník¶
knights = {"gallahad": "the pure", "robin": "the brave"}
for k, v in knights.items():
print(k, "->", v)
Typické použitie¶
- Ukladanie párov
nastavenie: hodnota
,meno: telefón
,slovo: počet výskytov
(ak chceme histogram/frekvencie). - Mapovanie ID -> objekt alebo reťazec -> iný reťazec.
Import a vytváranie objektov¶
from datetime import datetime, time
# v module je aj date, timedelta a iné triedy
# Objekt time (hodina, min, sek, mikrosekundy)
t = time(12, 45, 30)
print(t.hour, t.minute, t.second)
# datetime (rok, mesiac, den, hod, min, sek, mikrosek)
dt = datetime(2023, 9, 30, 10, 0, 0)
print(dt.year, dt.month, dt.day)
Aktuálny čas¶
now = datetime.now()
print("Teraz je:", now)
Formátovanie (strftime
)¶
%Y
celý rok (2024),%y
rok bez storočia (24)%m
mesiac (01-12)%d
deň v mesiaci (01-31)%H
hodina (00-23),%I
hodina (1-12)%M
minúta,%S
sekunda
print(now.strftime("%Y-%m-%d %H:%M:%S"))
# Napr. '2024-03-01 09:15:42'
Parsing (strptime
)¶
dt_str = "21/11/06 16:30"
dt_obj = datetime.strptime(dt_str, "%d/%m/%y %H:%M")
print(dt_obj) # 2006-11-21 16:30:00
Formát musí zodpovedať vstupnému reťazcu.
(Pozn.: Pre prácu so časovými zónami, relatívnym časom, atď. sú ďalšie knižnice, napr. pytz
, dateutil
.)
6. Pokročilé tipy a doplnky¶
Shallow vs. deep copy¶
- Shallow copy: skopíruje iba „vrchnú vrstvu“ zoznamu či dictu. Vnorené štruktúry zostanú zdieľané medzi originálom a kópiou.
- Deep copy: úplná rekurzívna kópia – používa sa
import copy
a funkciacopy.deepcopy()
.
Kedy stačí shallow? Napr. ak nepotrebujeme meniť obsahy vnorených štruktúr.
Comprehensions¶
Python umožňuje tzv. list comprehension, set comprehension a dict comprehension pre tvorbu kolekcií „v jednom riadku“ s prípadnou podmienkou.
List comprehension¶
numbers = [1, 2, 3, 4, 5]
squares = [x*x for x in numbers]
evens = [x for x in numbers if x % 2 == 0]
print(squares)
print(evens)
Dict comprehension¶
fruits = ["apple", "banana", "pear"]
lengths_dict = {fruit: len(fruit) for fruit in fruits}
print(lengths_dict) # napr. {'apple': 5, 'banana': 6, 'pear': 4}
Set comprehension¶
text = "hello world"
unique_chars = {ch for ch in text if ch != " "}
print(unique_chars) # {'d', 'e', 'h', 'l', 'o', 'r', 'w'}
Zhrnutie¶
V tejto prednáške sme prebrali kľúčové dátové štruktúry v Pythone – zoznamy, n-tice, množiny a slovníky – a základné metódy na manipuláciu s nimi. Okrem toho sme spomenuli prácu s dátumom a časom cez modul datetime
. Tieto kolekcie a typy sú najčastejšou súčasťou každodennej praxe v Pythone, či už pri malých skriptoch alebo pri rozsiahlych projektoch (od analýzy dát, cez web aplikácie, až po nástroje na spracovanie textu).
Odporúčaná literatúra/dokumentácia: