Nauč se Python > Kurzy > Začátečnický kurz PyLadies naruby > Slovníky > Slovníky

Slovníky #

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ý:

  • Jablko: Apple
  • Knoflík: Button
  • Myš: Mouse

Slovník v Pythonu obsahuje záznamy, a 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řebovala druhý slovník.

Měnění 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řebovala 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

Iterace #

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ěla 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 každou dvojici přímo rozbalíš 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

Existuje i metoda keys(), která vrací klíče.

To, co keys(), values() a items() vrací, jsou speciální objekty, které kromě použití ve for umožňují další operace: například pracovat s klíči jako s množinou. V dokumentaci Pythonu je to všechno popsáno.

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š.

Jak udělat slovník #

Slovník se dá vytvořit několika způsoby. První, pomocí složených závorek, jsi už viděla. 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".

Zaplň prázdný slovník #

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'])

Typy klíčů a hodnot #

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'

A to je zatím ke slovníkům vše #

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.


Toto je stránka lekce z kurzu, který probíhá nebo proběhl naživo s instruktorem.