Další základní datový typ, který si představíme –
po číslech, řetězcích, seznamech a n-ticích –
je slovník (angl. dictionary, dict
).
Představ si překladový slovník, třeba tenhle česko-anglický:
Slovník v Pythonu obsahuje záznamy. Každý záznam přiřazuje nějakému klíči nějakou hodnotu. V našem příkladu je klíči Jablko přiřazena hodnota Apple, klíči Knoflík náleží hodnota Button a klíč Myš ukazuje na Mouse.
V Pythonu by se takový slovník napsal následovně:
>>> slovnik = {'Jablko': 'Apple', 'Knoflík': 'Button', 'Myš': 'Mouse'}
>>> slovnik
{'Jablko': 'Apple', 'Knoflík': 'Button', 'Myš': 'Mouse'}
Pozor na všechny ty symboly! V tomhle slovníku jsou klíče i hodnoty řetězce, takže jsou v uvozovkách. Každý klíč je od své hodnoty oddělený dvojtečkou; jednotlivé dvojice jsou od sebe oddělené čárkou. A celý slovník je uzavřený ve složených závorkách.
Když budeš chtít v takovém slovníku něco najít, potřebuješ vědět co hledat. Konkrétně potřebuješ klíč. Ten dáš do hranatých závorek:
>>> slovnik['Jablko']
'Apple'
Je to podobné jako u seznamů, jen v hranatých závorkách není index (pořadové číslo prvku) nebo rozmezí s dvojtečkou, ale právě klíč.
Naopak to nejde – slovník neumožňuje podle hodnoty přímo zjistit klíč. Na překlad z angličtiny do češtiny bys potřeboval/a druhý slovník.
Co se stane, když klíč ve slovníku není?
>>> slovnik['Pes']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'Pes'
Python si postěžuje na KeyError
– chybu klíče.
Podobně jako seznamy se ale slovníky dají měnit. Nový záznam vytvoříš takhle:
>>> slovnik['Pes'] = 'Dog'
>>> slovnik
{'Jablko': 'Apple', 'Knoflík': 'Button', 'Myš': 'Mouse', 'Pes': 'Dog'}
Na rozdíl od překladového slovníku nemusí být Pythonní slovník seřazený podle abecedy. Není to potřeba, počítač umí rychle vyhledávat i bez seřazení.
Kdybys potřeboval/a změnit už existující záznam, použij stejný příkaz. K jednomu klíči může být přiřazena jen jedna hodnota.
>>> slovnik['Pes'] = 'Power strip'
>>> slovnik
{'Jablko': 'Apple', 'Knoflík': 'Button', 'Myš': 'Mouse', 'Pes': 'Power strip'}
Chceš-li ze slovníku nějaký záznam smazat, dělá se to podobně jako
u seznamů – příkazem del
:
>>> del slovnik['Pes']
>>> slovnik
{'Jablko': 'Apple', 'Knoflík': 'Button', 'Myš': 'Mouse'}
Když budeš chtít zjistit, kolik je ve slovníku záznamů,
zeptáš se podobně jako na počet znaků řetězce nebo prvků seznamu.
Použiješ funkci len()
.
>>> len(slovnik)
3
A pomocí in
můžeš zjistit, jestli slovník obsahuje daný klíč.
Funguje to opravdu jen pro klíče, ne pro přiřazené hodnoty:
>>> 'Myš' in slovnik
True
>>> 'Mouse' in slovnik
False
Když slovník projdeš cyklem for
, dostaneš klíče jednotlivých záznamů:
>>> for klic in slovnik:
... print(klic)
Jablko
Knoflík
Myš
Kdybys chtěl/a projít místo klíčů hodnoty, použij metodu values
,
která vrací iterátor hodnot:
>>> for hodnota in slovnik.values():
... print(hodnota)
Apple
Button
Mouse
Většinou ale potřebuješ jak klíče tak hodnoty.
K tomu mají slovníky metodu items
, která vrací iterátor dvojic.
Často využiješ možnost každou dvojici přímo rozbalit v cyklu for
,
jako se to dělá se zip
nebo enumerate
:
>>> for klic, hodnota in slovnik.items():
... print('{}: {}'.format(klic, hodnota))
Jablko: Apple
Knoflík: Button
Myš: Mouse
V průběhu iterace (tedy v rámci for
cyklu) nesmíš
do slovníku přidávat záznamy, ani záznamy odebírat:
>>> for klic in slovnik:
... del slovnik[klic]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
Hodnoty u už existujících klíčů ale měnit můžeš.
Slovník se dá vytvořit několika způsoby.
První, pomocí složených závorek, jsi už viděl/a.
Další způsob využívá funkci dict
.
Ta, ve stylu str
, int
či list
, převede cokoli co jde na slovník.
Slovník je ovšem dost specifická struktura – čísla ani většina seznamů na něj převést nejdou. Můžeš ale na slovník převést jiný slovník. Nový slovník pak žije svým vlastním životem; můžeš ho měnit nezávisle na tom původním.
Druhá věc, která jde převést na slovník, je sekvence dvojic klíč/hodnota – ať už seznam:
>>> data = [(1, 'jedna'), (2, 'dva'), (3, 'tři')]
>>> nazvy_cisel = dict(data)
>>> nazvy_cisel
{1: 'jedna', 2: 'dva', 3: 'tři'}
nebo jiný iterovatelný objekt:
>>> data = enumerate(['nula', 'jedna', 'dva'])
>>> nazvy_cisel = dict(data)
>>> nazvy_cisel
{0: 'nula', 1: 'jedna', 2: 'dva'}
A to je vše, co se na slovník dá převést.
Jako bonus umí funkce dict
ještě
brát pojmenované argumenty.
Každé jméno argumentu převede na řetězec,
použije ho jako klíč, a přiřadí danou hodnotu:
popisy_funkci = dict(len='délka', str='řetězec', dict='slovník')
print(popisy_funkci['len'])
Pozor na to, že v tomhle případě musí být klíče
pythonní „jména“ – musí být použitelné jako jména proměnných.
Například takhle nejde zadat jako klíč řetězec
"def"
nebo "propan-butan"
.
Nejobecnější způsob vytváření slovníků je podobný tomu co znáš u seznamů: vytvoř prázdný slovník a postupně do něj přidávej záznamy, jeden za druhým.
Řekněme, že máš slovník, který přiřazuje ovoci jeho barvu:
barvy = {
'hruška': 'zelená',
'jablko': 'červená',
'meloun': 'zelená',
'švestka': 'modrá',
'ředkvička': 'červená',
'zelí': 'zelená',
'mrkev': 'červená',
}
Následující kód vytvoří slovník se změněnými barvami:
barvy_po_tydnu = {}
for ovoce, barva in barvy.items():
barvy_po_tydnu[ovoce] = 'černo-hnědo-' + barva
print(barvy_po_tydnu['jablko'])
Do slovníku můžeš uložit jakoukoli hodnotu: řetězce, seznamy, nebo čísla.
uzivatel = {'jméno': 'Amálka', 'velikost nohy': 36, 'oblíbená čísla': [5, 27]}
Jako klíč jde ovšem použít jen hodnoty, podle kterých pak Python umí záznam rychle najít. A to nejsou všechny. Řetězce a čísla použít jdou:
jmena_cisel = {2: 'dva', 3: 'tři'}
Ale seznamy nebo jiné slovníky ne. Typy které se dají použít jako klíč ve slovníku se technicky označují jako „hashovatelné“ (angl. hashable). Tento termín se objevuje v chybových hláškách:
>>> jmena_seznamu = {[1, 2, 3]: 'čísla', ['a', 'b', 'c']: 'řetězce'}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
N-tice jsou hashovatelné, pokud obsahují jen hashovatelné hodnoty:
>>> figurky = {('c', 1): 'bílý střelec', ('e', 8): 'černý král'}
>>> figurky['c', 1]
'bílý střelec'
>>> jmena = {([1, 2, 3], [3, 4, 5]): 'dvojice seznamů'}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
Chceš-li mít všechny triky, které slovníky umí, pěkně pohromadě, můžeš si stáhnout Slovníkový tahák.
Kompletní popis slovníků najdeš v dokumentaci Pythonu.