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
).
Podobně jako seznamy, slovníky v sobě obsahují další hodnoty. Na rozdíl od seznamů, ve kterých jsou všechny prvky uspořádané do jedné 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 jedna 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]}
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
{'jméno': 'Anna', 'město': 'Brno', 'čísla': [3, 7, 42]}
... nebo přidávat:
>>> ja['jazyk'] = 'Python'
>>> ja
{'jméno': 'Anna', 'město': 'Brno', 'čísla': [3, 7, 42], 'jazyk': 'Python'}
... nebo ubírat příkazem del
, podobně jako u seznamů:
>>> del ja['čísla']
>>> ja
{'jméno': 'Anna', 'město': 'Brno', 'jazyk': 'Python'}
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.
Taková tabulka se hodí vždycky, když je potřeba přiřadit nějaké hodnoty jiným hodnotám. Jako v telefonním seznamu, kde každému jménu přísluší nějaké číslo, nebo v překladovém slovníku, kde jsou slovům přiřazeny překlady.
cisla = {
'Maruška': '153 85283',
'Terka': '237 26505',
'Renata': '385 11223',
'Michal': '491 88047',
}
barvy = {
'hruška': 'zelená',
'jablko': 'červená',
'meloun': 'zelená',
'švestka': 'modrá',
'ředkvička': 'červená',
'zelí': 'zelená',
'mrkev': 'červená',
}
Když dáš slovník do cyklu for
, dostaneš klíče:
>>> popisy_funkci = {'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á bude v cyklu for
dávat dvojice:
>>> 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žň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 takového for
cyklu nesmíš
do slovníku přidávat záznamy, ani záznamy odebírat:
>>> for klic in popisy_funkci:
... del popisy_funkci[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 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
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"
.
Pojmenované argumenty jde kombinovat s ostatními
způsoby vytvoření dict
.
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.
{ "data": { "sessionMaterial": { "id": "session-material:2018/pyladies-ostrava-jaro:dict:0", "title": "SlovnĂky", "html": "\n \n \n\n <h1>Slovníky</h1>\n<p>Další základní datový typ, který si představíme –\npo číslech, řetězcích, seznamech a <var>n</var>-ticích –\njsou <em>slovníky</em> (angl. <em>dictionary</em>, <code>dict</code>).</p>\n<p>Podobně jako seznamy, slovníky v sobě obsahují další hodnoty.\nNa rozdíl od seznamů, ve kterých jsou všechny prvky\nuspořádané do jedné sekvence, ve slovnících máme dva druhy\nprvků: takzvaný <em>klíč</em> (angl. <em>key</em>) a <em>hodnotu</em> (angl. <em>value</em>).\nKaždému klíči je přiřazena jedna hodnota.</p>\n<p>Slovník můžeš použít, když máš několik kousků\ninformací, které se dají pojmenovat, ale chceš s nimi\npracovat jako s jednou proměnnou.</p>\n<p>Tady je slovník, který má tři klíče, a k nim příslušné tři hodnoty:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">>>> </span><span class=\"n\">ja</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s1\">'jméno'</span><span class=\"p\">:</span> <span class=\"s1\">'Anna'</span><span class=\"p\">,</span> <span class=\"s1\">'město'</span><span class=\"p\">:</span> <span class=\"s1\">'Brno'</span><span class=\"p\">,</span> <span class=\"s1\">'čísla'</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">7</span><span class=\"p\">]}</span>\n</pre></div><p>Hodnoty ze slovníku můžeš získat podobně jako\nze seznamu, jen místo indexu (pozice) použiješ klíč:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">>>> </span><span class=\"n\">ja</span><span class=\"p\">[</span><span class=\"s1\">'jméno'</span><span class=\"p\">]</span>\n<span class=\"go\">'Anna'</span>\n</pre></div><p>Zeptáš-li se na neexistující klíč, nebude se to Pythonu líbit:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">>>> </span><span class=\"n\">ja</span><span class=\"p\">[</span><span class=\"s1\">'věk'</span><span class=\"p\">]</span>\n<span class=\"gt\">Traceback (most recent call last):</span>\n File <span class=\"nb\">"<stdin>"</span>, line <span class=\"m\">1</span>, in <span class=\"n\">&lt;module&gt;</span>\n<span class=\"gr\">KeyError</span>: <span class=\"n\">'věk'</span>\n</pre></div><p>Hodnoty jdou podle klíče i měnit:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">>>> </span><span class=\"n\">ja</span><span class=\"p\">[</span><span class=\"s1\">'čísla'</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"mi\">42</span><span class=\"p\">]</span>\n<span class=\"gp\">>>> </span><span class=\"n\">ja</span>\n<span class=\"go\">{'jméno': 'Anna', 'město': 'Brno', 'čísla': [3, 7, 42]}</span>\n</pre></div><p>... nebo přidávat:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">>>> </span><span class=\"n\">ja</span><span class=\"p\">[</span><span class=\"s1\">'jazyk'</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s1\">'Python'</span>\n<span class=\"gp\">>>> </span><span class=\"n\">ja</span>\n<span class=\"go\">{'jméno': 'Anna', 'město': 'Brno', 'čísla': [3, 7, 42], 'jazyk': 'Python'}</span>\n</pre></div><p>... nebo ubírat příkazem <code>del</code>, podobně jako u seznamů:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">>>> </span><span class=\"k\">del</span> <span class=\"n\">ja</span><span class=\"p\">[</span><span class=\"s1\">'čísla'</span><span class=\"p\">]</span>\n<span class=\"gp\">>>> </span><span class=\"n\">ja</span>\n<span class=\"go\">{'jméno': 'Anna', 'město': 'Brno', 'jazyk': 'Python'}</span>\n</pre></div><h2>Vyhledávací tabulka</h2>\n<p>Trochu jiné použití slovníku, než sdružování\n„různých“ typů informací, je takzvaná\n<em>vyhledávací tabulka</em> (angl. <em>lookup table</em>).\nV ní mají typicky všechny hodnoty stejný typ.</p>\n<p>Taková tabulka se hodí vždycky, když je potřeba\npřiřadit nějaké hodnoty jiným hodnotám.\nJako v telefonním seznamu, kde každému jménu přísluší\nnějaké číslo, nebo v překladovém slovníku, kde jsou slovům\npřiřazeny překlady.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">cisla</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n <span class=\"s1\">'Maruška'</span><span class=\"p\">:</span> <span class=\"s1\">'153 85283'</span><span class=\"p\">,</span>\n <span class=\"s1\">'Terka'</span><span class=\"p\">:</span> <span class=\"s1\">'237 26505'</span><span class=\"p\">,</span>\n <span class=\"s1\">'Renata'</span><span class=\"p\">:</span> <span class=\"s1\">'385 11223'</span><span class=\"p\">,</span>\n <span class=\"s1\">'Michal'</span><span class=\"p\">:</span> <span class=\"s1\">'491 88047'</span><span class=\"p\">,</span>\n<span class=\"p\">}</span>\n\n<span class=\"n\">barvy</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n <span class=\"s1\">'hruška'</span><span class=\"p\">:</span> <span class=\"s1\">'zelená'</span><span class=\"p\">,</span>\n <span class=\"s1\">'jablko'</span><span class=\"p\">:</span> <span class=\"s1\">'červená'</span><span class=\"p\">,</span>\n <span class=\"s1\">'meloun'</span><span class=\"p\">:</span> <span class=\"s1\">'zelená'</span><span class=\"p\">,</span>\n <span class=\"s1\">'švestka'</span><span class=\"p\">:</span> <span class=\"s1\">'modrá'</span><span class=\"p\">,</span>\n <span class=\"s1\">'ředkvička'</span><span class=\"p\">:</span> <span class=\"s1\">'červená'</span><span class=\"p\">,</span>\n <span class=\"s1\">'zelí'</span><span class=\"p\">:</span> <span class=\"s1\">'zelená'</span><span class=\"p\">,</span>\n <span class=\"s1\">'mrkev'</span><span class=\"p\">:</span> <span class=\"s1\">'červená'</span><span class=\"p\">,</span>\n<span class=\"p\">}</span>\n</pre></div><h2>Iterace</h2>\n<p>Když dáš slovník do cyklu <code>for</code>, dostaneš klíče:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">>>> </span><span class=\"n\">popisy_funkci</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s1\">'len'</span><span class=\"p\">:</span> <span class=\"s1\">'délka'</span><span class=\"p\">,</span> <span class=\"s1\">'str'</span><span class=\"p\">:</span> <span class=\"s1\">'řetězec'</span><span class=\"p\">,</span> <span class=\"s1\">'dict'</span><span class=\"p\">:</span> <span class=\"s1\">'slovník'</span><span class=\"p\">}</span>\n<span class=\"gp\">>>> </span><span class=\"k\">for</span> <span class=\"n\">klic</span> <span class=\"ow\">in</span> <span class=\"n\">popisy_funkci</span><span class=\"p\">:</span>\n<span class=\"gp\">... </span> <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">klic</span><span class=\"p\">)</span>\n<span class=\"go\">str</span>\n<span class=\"go\">dict</span>\n<span class=\"go\">len</span>\n</pre></div><p>Pokud chceš hodnoty, stačí použít metodu <code>values</code>:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">>>> </span><span class=\"k\">for</span> <span class=\"n\">hodnota</span> <span class=\"ow\">in</span> <span class=\"n\">popisy_funkci</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">():</span>\n<span class=\"gp\">... </span> <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">hodnota</span><span class=\"p\">)</span>\n<span class=\"go\">řetězec</span>\n<span class=\"go\">slovník</span>\n<span class=\"go\">délka</span>\n</pre></div><p>Většinou ale potřebuješ jak klíče tak hodnoty.\nK tomu mají slovníky metodu <code>items</code>,\nkterá bude v cyklu <code>for</code> dávat dvojice:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"gp\">>>> </span><span class=\"k\">for</span> <span class=\"n\">klic</span><span class=\"p\">,</span> <span class=\"n\">hodnota</span> <span class=\"ow\">in</span> <span class=\"n\">popisy_funkci</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n<span class=\"gp\">... </span> <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">'{}: {}'</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"n\">klic</span><span class=\"p\">,</span> <span class=\"n\">hodnota</span><span class=\"p\">))</span>\n<span class=\"go\">str: řetězec</span>\n<span class=\"go\">dict: slovník</span>\n<span class=\"go\">len: délka</span>\n</pre></div><div class=\"admonition note\"><p>Existuje i metoda <code>keys()</code>, která vrací klíče.</p>\n<p>To, co <code>keys()</code>, <code>values()</code> a <code>items()</code> vrací, jsou speciální objekty,\nkteré kromě použití ve <code>for</code> umožňují další\noperace: například pracovat s klíči jako s množinou.\nV <a href=\"https://docs.python.org/3.0/library/stdtypes.html#dictionary-view-objects\">dokumentaci</a>\nPythonu je to všechno popsáno.</p>\n</div><p>V průběhu takového <code>for</code> cyklu nesmíš\ndo slovníku přidávat záznamy, ani záznamy odebírat:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"o\">>>></span> <span class=\"k\">for</span> <span class=\"n\">klic</span> <span class=\"ow\">in</span> <span class=\"n\">popisy_funkci</span><span class=\"p\">:</span>\n<span class=\"o\">...</span> <span class=\"k\">del</span> <span class=\"n\">popisy_funkci</span><span class=\"p\">[</span><span class=\"n\">klic</span><span class=\"p\">]</span>\n<span class=\"n\">Traceback</span> <span class=\"p\">(</span><span class=\"n\">most</span> <span class=\"n\">recent</span> <span class=\"n\">call</span> <span class=\"n\">last</span><span class=\"p\">):</span>\n <span class=\"n\">File</span> <span class=\"s2\">"<stdin>"</span><span class=\"p\">,</span> <span class=\"n\">line</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"ow\">in</span> <span class=\"o\"><</span><span class=\"n\">module</span><span class=\"o\">></span>\n<span class=\"ne\">RuntimeError</span><span class=\"p\">:</span> <span class=\"n\">dictionary</span> <span class=\"n\">changed</span> <span class=\"n\">size</span> <span class=\"n\">during</span> <span class=\"n\">iteration</span>\n</pre></div><p>Hodnoty u už existujících klíčů ale měnit můžeš.</p>\n<h2>Jak udělat slovník</h2>\n<p>Slovník se dá vytvořit dvěma způsoby.\nPrvní, pomocí {složených závorek}, jsme už viděly;\ndalší využívají funkci <code>dict</code>.\nTa, ve stylu <code>str</code>, <code>int</code> či <code>list</code>, převede cokoli, co jde, na slovník.</p>\n<p>Slovník je ovšem dost specifická struktura –\nčísla nebo typické seznamy na něj převádět nejdou.\nMůžeme ale na slovník převést <em>jiný slovník</em>.\nNový slovník žije svým vlastním životem;\nnásledné změny se promítnou jen do něj.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">barvy_po_tydnu</span> <span class=\"o\">=</span> <span class=\"nb\">dict</span><span class=\"p\">(</span><span class=\"n\">barvy</span><span class=\"p\">)</span>\n<span class=\"k\">for</span> <span class=\"n\">klic</span> <span class=\"ow\">in</span> <span class=\"n\">barvy_po_tydnu</span><span class=\"p\">:</span>\n <span class=\"n\">barvy_po_tydnu</span><span class=\"p\">[</span><span class=\"n\">klic</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s1\">'černo-hnědo-'</span> <span class=\"o\">+</span> <span class=\"n\">barvy_po_tydnu</span><span class=\"p\">[</span><span class=\"n\">klic</span><span class=\"p\">]</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">barvy</span><span class=\"p\">[</span><span class=\"s1\">'jablko'</span><span class=\"p\">])</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">barvy_po_tydnu</span><span class=\"p\">[</span><span class=\"s1\">'jablko'</span><span class=\"p\">])</span>\n</pre></div><p>Druhá věc, která jde převést na slovník, je\n<em>sekvence dvojic</em> klíč/hodnota:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"s1\">'jedna'</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"s1\">'dva'</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"s1\">'tři'</span><span class=\"p\">)]</span>\n<span class=\"n\">nazvy_cisel</span> <span class=\"o\">=</span> <span class=\"nb\">dict</span><span class=\"p\">(</span><span class=\"n\">data</span><span class=\"p\">)</span>\n</pre></div><p>A to je vše, co se na slovník dá převést.</p>\n<p>Jako bonus umí funkce <code>dict</code> ještě\nbrát pojmenované argumenty.\nKaždé jméno argumentu převede na řetězec,\npoužije ho jako klíč, a přiřadí danou hodnotu:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">popisy_funkci</span> <span class=\"o\">=</span> <span class=\"nb\">dict</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"o\">=</span><span class=\"s1\">'délka'</span><span class=\"p\">,</span> <span class=\"nb\">str</span><span class=\"o\">=</span><span class=\"s1\">'řetězec'</span><span class=\"p\">,</span> <span class=\"nb\">dict</span><span class=\"o\">=</span><span class=\"s1\">'slovník'</span><span class=\"p\">)</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">popisy_funkci</span><span class=\"p\">[</span><span class=\"s1\">'len'</span><span class=\"p\">])</span>\n</pre></div><div class=\"admonition note\"><p>Pozor na to, že v tomhle případě musí být klíče\npythonní „jména“ – musí být použitelné jako jména proměnných.\nNapříklad takhle nejde zadat jako klíč řetězec\n<code>"def"</code> nebo <code>"propan-butan"</code>.</p>\n</div><p>Pojmenované argumenty jde kombinovat s ostatními\nzpůsoby vytvoření <code>dict</code>.</p>\n<h2>A to je zatím ke slovníkům vše</h2>\n<p>Chceš-li mít všechny triky, které slovníky umí,\npěkně pohromadě, můžeš si stáhnout\n<a href=\"https://pyvec.github.io/cheatsheets/dicts/dicts-cs.pdf\">Slovníkový tahák</a>.</p>\n<p>Kompletní popis slovníků najdeš\nv <a href=\"https://docs.python.org/3.0/library/stdtypes.html#mapping-types-dict\">dokumentaci</a>\nPythonu.</p>\n\n\n " } } }