Slovník
V této kapitole si rozšíříme znalosti o datových typech, které umožňují uchovávat více dat najednou. Už jsme poznali seznamy (pole), tedy lineární kolekce, kterými můžeme iterovat a ke kterým můžeme přistupovat pomocí indexů.
Slovník (anglicky dictionary, ale také map, hashmap, hashtable, associative array; mapa, hashmapa, hashovací tabulka, asociativní seznam) je datová struktura, která umožňuje uchovávat páry klíč-hodnota (narozdíl od pole, které uchovává pouze hodnoty). Název “asociativní seznam” si získal proto, že se slovníkem dá iterovat podobně jako seznamem, ale zároveň asociuje hodnoty klíče s jejich přidruženými hodnotami. Český název “slovník” si získal proto, že funguje podobně jako slovník jazykový: pokud chceme přeložit slovo “apple” (klíč) do češtiny, nalistujeme v knize na stránku, kde se “apple” vyskytuje a přečteme překlad (hodnotu).
Ve slovnících můžeme uchovávat libovolné datové typy jako klíče nebo hodnoty.
Pořídíme si prázdný slovník, kterým budeme simulovat anglicko-český jazykový slovník:
slovnik = {}
Do slovníku následně přidáme některé anglicky-české překlady:
slovnik["apple"] = "jablko"
slovnik["banana"] = "banán"
slovnik["orange"] = "pomeranč"
Pokud nás zajímá překlad slova “banana”, můžeme ho získat pomocí tohoto klíče:
print(slovnik["banana"])
Záludnost nastává v momentě, kdybychom chtěli přeložit slovo “apricot”. Toto slovo ve slovníku není a Python na nás zakřičí výjimku (zkuste si to):
print(slovnik["apricot"])
Dostaneme výjimku KeyError, protože klíč “apricot” není v slovníku. Kdyby se toto stalo uprostřed běhu programu, běh
by se zastavil a Python vypsal výjimku. Občas ale potřebujeme získat hodnotu pro klíč, který není v slovníku, a to bez
zastavení programu možnou výjimkou. Můžeme to provést pomocí slovíčka get():
print(slovnik.get("apricot"))
Co ale get vrátí, když klíč není v slovníku? V tomto případě vrátí None, což je speciální hodnota, která
reprezentuje “nic”. Ano, je to trochu zvláštní, že “nic” můžeme zhmotnit do hodnoty, ale co už… K hodnotě, o které
si nejsme jisti, zdali ve slovníku je, můžeme bezpečně přistoupit takto:
chci_prelozit = "apricot"
hledane_slovo = slovnik.get(chci_prelozit)
if hledane_slovo is not None:
print(f"{chci_prelozit} se přeloží na {hledane_slovo}.")
else:
print(f"{chci_prelozit} není v slovníku.")
Pozor na to, jak ověřujeme to, jestli je v proměnné hodnotě None nebo ne: is not None a analogicky is None.
Tuto konstrukci používáme výhradně pro None a nepoužíváme ji nikde jinde; pro ostatní případy použijeme klasické
porovnávací operátory z kapitoly o podmíněných příkazech.
Použítí .get() se můžeme vyhnout tím, že předem ověříme, jestli je klíč ve slovníku:
chci_prelozit = "apricot"
if chci_prelozit in slovnik:
hledane_slovo = slovnik[chci_prelozit]
print(f"{chci_prelozit} se přeloží na {hledane_slovo}.")
else:
print(f"{chci_prelozit} není v slovníku.")
Slovíčko get má další variantu, která nám umožní nastavit výchozí hodnotu, která se nám vrátí, pokud ve slovníku klíč
není:
body = {"David": 10}
vysledek = body.get("David", 0)
print(vysledek)
vysledek = body.get("Jan", 0)
print(vysledek)
Slovníkem také můžeme iterovat pomocí .items():
for key, value in slovnik.items():
print(f"{key}: {value}")
Pokud chceme iterovat pouze přes klíče nebo hodnoty, můžeme použít .keys() nebo .values():
for key in slovnik.keys():
print(key)
for value in slovnik.values():
print(value)
Jak items(), tak i keys() a values() vrací seznamy.
Úlohy
- Počítání písmen
- Na vstupu dostanete od uživatele řetězec. Váš úkol je pro každé písmeno v řetězci spočítat, kolikrát se v něm vyskytuje.
Použijte slovník, kde klíče budou písmena a hodnoty jejich četnost v řetězci. Doporučuji použít variantu
gets výchozí hodnotou 0. Řetězcem na vstupu můžete iterovat právě jednou. - Telefonní seznam
- Od uživatele dostanete na vstupu jméno a telefonní číslo, přičemž byste měli uživateli umožnit přidat takových záznamů více. Po zadání ničeho do vstupu pro nové jméno do seznamu se ukončí zadávání a program se přepne do režimu pro vyhledávání. Na vstupu teď budete požadovat jen jméno, podle kterého program vyhledá telefonní číslo. Pokud neexistuje, vypište chybovou hlášku a nechte uživatele zadat jméno znovu.