PyLadies Brno

Slovníky

Další základní datový typ, který si představíme – po číslech, řetězcích, seznamech a n-ticích – jsou slovníky (angl. dictionary, dict).
Jako seznamy, slovníky obsahují další hodnoty. Na rozdíl od seznamů, ve kterých jsou všechny prvky uspořádané do sekvence, ve slovnících máme dva druhy prvků: takzvaný klíč (angl. key) a hodnotu (angl. value). Každému klíči je přiřazena nějaká hodnota.
Slovník můžeš použít, když máš několik kousků informací, které se dají pojmenovat, ale chceš s nimi pracovat jako s jednou proměnnou.
Tady je slovník, který má tři klíče, a k nim příslušné tři hodnoty:
ja = {'jméno': 'Anna', 'město': 'Brno', 'čísla': [3, 7]}
Když slovník vypíšeš, pravděpodobně zjistíš, se klíče a hodnoty vypíšou v jiném pořadí. Slovníky totiž, na rozdíl od seznamů, nemají dané pořadí prvků – jen přiřazují hodnoty klíčům.
Hodnoty ze slovníku můžeš získat podobně jako ze seznamu, jen místo indexu (pozice) použiješ klíč:
>>> ja['jméno']
'Anna'
Zeptáš-li se na neexistující klíč, nebude se to Pythonu líbit:
>>> ja['věk']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'věk'
Hodnoty jdou podle klíče i měnit:
>>> ja['čísla'] = [3, 7, 42]
>>> ja
{'čísla': [3, 7, 42], 'jméno': 'Anna', 'město': 'Brno'}
... nebo přidávat:
>>> ja['jazyk'] = 'Python'
>>> ja
{'jazyk': 'Python', 'čísla': [3, 7, 42], 'jméno': 'Anna', 'město': 'Brno'}
... nebo ubírat (příkazem del, podobně jako u seznamů):
>>> del ja['čísla']
>>> ja
{'jazyk': 'Python', 'jméno': 'Anna', 'město': 'Brno'}

Vyhledávací tabulka

Trochu jiné použití slovníku, než sdružování „různých“ typů informací, je takzvaná vyhledávací tabulka (angl. lookup table). V ní mají typicky všechny hodnoty stejný typ.
barvy = {
    'hruška': 'zelená',
    'jablko': 'červená',
    'meloun': 'zelená',
    'švestka': 'modrá',
    'ředkvička': 'červená',
    'zelí': 'zelená',
    'mrkev': 'červená',
}

Jak udělat slovník

Slovník se dá vytvořit dvěma způsoby. První, pomocí {složených závorek}, jsme už viděly; další využívají 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 nebo typické seznamy na něj převádět nejdou. Můžeme ale na slovník převést jiný slovník. Nový slovník žije svým vlastním životem; následné změny se promítnou jen do něj.
barvy_po_tydnu = dict(barvy)
for klic in barvy_po_tydnu:
    barvy_po_tydnu[klic] = 'černo-hnědo-' + barvy_po_tydnu[klic]
print(barvy['jablko'])
print(barvy_po_tydnu['jablko'])
Druhá věc, která jde převést na slovník, je sekvence dvojic klíč/hodnota:
data = [(1, 'jedna'), (2, 'dva'), (3, 'tři')]
nazvy_cisel = dict(data)
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 pythoní „jména“ – musí být použitelné jako jména proměnných. Například takhle nejde zadat klíč "def" či "propan-butan".
Pojmenované argumenty jde kombinovat s ostatními způsoby vytvoření dict.

Iterace

Když dáš slovník do cyklu for, dostaneš klíče:
>>> popisy_funkci = dict(len='délka', str='řetězec', dict='slovník')
>>> for klic in popisy_funkci:
...     print(klic)
str
dict
len
Pokud chceš hodnoty, stačí použít metodu values:
>>> for hodnota in popisy_funkci.values():
...     print(hodnota)
řetězec
slovník
délka
Většinou ale potřebuješ jak klíče tak hodnoty. K tomu mají slovníky metodu items, která vrátí „něco jako seznam” dvojic:
>>> for klic, hodnota in popisy_funkci.items():
...     print('{}: {}'.format(klic, hodnota))
str: řetězec
dict: slovník
len: délka
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žňuje další operace: například pracovat s klíči jako s množinou. V dokumentaci Pythonu je to všechno popsáno.
Slovník nesmíš v průběhu takového for cyklu měnit.
>>> for klic in popisy_funkci:
...     del popisy_funkci[klic]
Traceback (most recent call last):
  File "", line 1, in 
RuntimeError: dictionary changed size during iteration
Přesněji řečeno, můžeš měnit hodnoty u už existujících klíčů, ale nesmíš přidávat nebo ubírat záznamy.

Slovníkový tahák

Tady jsou operace, které slovníky podporují – včetně těch, které v úvodu výše nejsou.
Popis Příklad
{k: v, ...} Vytvoření slovníku d = {1: 'jedna', 2: 'dva'}
len(d) Počet záznamů len(d)
d[k] Hodnota přiřazená klíči k d[1]
d[k] = v Přiřazení hodnoty v klíči k d[3] = 'tři'
del d[k] Odebrání klíče k, a příslušné hodnoty del d[2]
d.get(k) Hodnota příslušící klíči k; pokud ten klíč neexistuje, vrátí se None. d.get(4, '?')
d.get(k,d) Hodnota příslušící klíči k; pokud ten klíč neexistuje, vrátí se d. d.get(4, '?')
d.pop(k) Odebrání klíče k, vrácení příslušné hodnoty v = d.pop(3)
d.pop(k, d) Jako pop(k), ale pokud klíč neexistuje, místo chyby vrací d v = d.pop(3, '?')
d.popitem() Odebere a vrátí některou dvojici (klíč, hodnota) ze slovníku. (Nedá se spolehnout na to, kterou přesně.) k, v = d.popitem()
d.setdefault(k, v) Pokud klíč k není ve slovníku, přidá ho s hodnotou v; vrátí hodnotu příslušící klíči k d.setdefault(1, 'JEDNA')
d.update(d2) Přidá všechny klíče/hodnoty slovníku d2 d.update({7: 'sedm', 8: 'osm'})
for k in d: Iterace nad klíči slovníku list(d)
d.keys() "Zobrazení" klíčů slovníku list(d.keys())
d.values() "Zobrazení" hodnot slovníku list(d.values())
d.items() "Zobrazení" dvojic (klíč, hodnota) for k, v in d.items():
d.copy() Kopie slovníku d2 = d.copy()
d.clear() Vyprázdnění slovníku d.clear()
Kompletní popis slovníků najdeš v dokumentaci Pythonu.