8. diel - ChainMap, NamedTuple a DeQue v Pythone
V minulej lekcii, Komprehencie, lambda výrazy a funkcie v Pythone , sme si ukázali zoznamové komprehencie, lambda výrazy a niektoré vstavané funkcie pre prácu s iterovateľnými objektmi.
V tomto tutoriále kolekcií v Pythone sa budeme venovať
trom ich zástupcom. Konkrétne sa zameriame na triedy ChainMap
,
NamedTuple
a Deque
z modulu
collections
.
ChainMap
ChainMap
je dátový typ, ktorý nám umožňuje
združovať viac slovníkov do jedného logického celku. Inými
slovami nám ChainMap
umožňuje jednoducho a efektívne
pracovať s viacerými slovníkmi ako s jedným.
ChainMap
sa často používa v prípade, keď chceme hľadať
hodnotu pre kľúč vo viacerých slovníkoch. Veľkou výhodou
ChainMap
je, že nám umožňuje udržiavať všetky slovníky v
jednom objekte. Hľadanie v združených slovníkoch bude
prebiehať postupne v poradí, v akom boli uvedené pri vytvorení inštancie,
kým sa pre kľúč nenájde zodpovedajúca hodnota.
Príklad použitia
ChainMap
Použitie ChainMap
v Pythone je veľmi jednoduché. Prvým
krokom je importovať modul collections
. Ďalej si nadefinujeme
slovníky slovnik1
a slovnik2
a potom vytvoríme
premennú mapa
, ktorá bude obsahovať inštanciu triedy
ChainMap
:
from collections import ChainMap slovnik1 = {'a':1, 'b':2} slovnik2 = {'c':3, 'b':4} mapa = ChainMap(slovnik1, slovnik2)
Následne si vypíšeme obsah premennej mapa
a na ďalšom
riadku výpis zopakujeme pre index ['b']
:
print(mapa) print(mapa['b'])
Výstupom v konzole bude:
Konzolová aplikácia
ChainMap({'a': 1, 'b': 2}, {'c': 3, 'b': 4})
2
Vidíme, že premenná mapa
sa správa ako slovník, v ktorom
sú uložené hodnoty zo slovnik1
a slovnik2
.
Následný výpis print(mapa['b'])
vracia hodnotu kľúča
b
z prvého slovníka, v ktorom je k dispozícii, tj zo
slovnik1
.
Teraz si vyskúšame obsah premennej mapa
modifikovať. Pridáme
riadok s kódom mapa['c'] = 5
. Tým pridáme do premennej
mapa
nový kľúč c
s hodnotou 5
. Tieto
zmeny sa prejavia v premennej mapa
, ale nie v pôvodných
slovníkoch:
mapa['c'] = 5 print(mapa)
V konzole teda uvidíme:
Konzolová aplikácia
ChainMap({'a': 1, 'b': 2, 'c': 5}, {'c': 3, 'b': 4})
Teraz modifikujeme jeden zo slovníkov a opäť si vypíšeme obsah premennej
mapa
:
slovnik2['c'] = 6 print(mapa)
Výstup v konzole bude:
Konzolová aplikácia
ChainMap({'a': 1, 'b': 2, 'c': 5}, {'c': 6, 'b': 4})
Vidíme, že hodnota kľúča c
sa v premennej mapa
sa zmenila na 6
, pretože sa na 6
zmenila aj v
podkladovom slovníku (slovnik2['c'] = 6
).
Metódy pre prácu s
ChainMap
Trieda ChainMap
obsahuje okrem iného nasledujúce metódy:
maps
- vráti novú inštanciuChainMap
, ktorá pridá zadaný slovník (alebo slovníky) na koniec zoznamu slovníkov,new_child()
- pridá nový slovník na prvú pozíciu v zozname,get(key[, default])
- vráti hodnotu pre daný kľúč. Ak hodnota nie je nájdená, vráti hodnotu default (ak je zadaná), inak vyvolá výnimkuKeyError
,keys()
- vráti zoznam všetkých kľúčov,values()
- vráti zoznam všetkých hodnôt,items()
- vráti zoznam všetkých položiek vo formáte (kľúč, hodnota).
ChainMap
je
aktualizovateľný pohľad nad viacerými slovníkmi. Hodnoty v
príslušnej inštancii sa menia v závislosti na zmenách v
jednotlivých podkladových slovníkoch.
NamedTuple
Trieda NamedTuple
je špeciálny prípad nezoradeného
dátového typu, ktorý kombinuje výhody tuple a slovníka. Rovnako ako tuple
má aj pevnú dĺžku a jej inštancie nemožno modifikovať. Zásadný rozdiel
ale spočíva v tom, že jednotlivé položky môžu byť prístupné pomocou
mena (rovnako ako v prípade slovníka).
Výhodou NamedTuple
teda je, že umožňuje jasnejší a
čitateľnejší kód, pretože mená položiek sú priamo súčasťou kódu.
Vďaka pevnej dĺžke je tiež efektívnejšie ako použitie slovníka.
Príklad použitia
NamedTuple
NamedTuple
sa vytvára pomocou funkcie
namedtuple()
. Najprv si triedu NamedTuple
naimportujeme z modulu collections
. Potom pomocou funkcie
namedtuple()
vytvoríme triedu Osoba
, ktorá
rozširuje NamedTuple
o položky jmeno
,
prijmeni
a vek
. Následne vytvoríme premennú
student
, v ktorej bude inštancia triedy Osoba
:
from collections import namedtuple Osoba = namedtuple("Osoba", ["jmeno", "prijmeni", "vek"]) student = Osoba("Jan", "Novák", 26)
K položkám NamedTuple
potom budeme pristupovať pomocou mena
položky ako atribútu inštancie, ako by išlo o obyčajné atribúty
triedy:
print("Jméno a příjmení studenta: "+ student.jmeno + " " + student.prijmeni) print("Věk studenta:", student.vek)
V konzole vidíme výstup:
Konzolová aplikácia
Jméno a příjmení studenta: Jan Novák
Věk studenta: 26
Nasledujúcim spôsobom potom vypíšeme celú inštanciu
NamedTuple
z premennej turista
:
from collections import namedtuple Turista = namedtuple('Turista', ['jmeno', 'vek', 'zeme']) turista = Turista('Jan', 26, 'Norsko') print(turista)
Výstupom v konzole bude:
Konzolová aplikácia
Turista(jmeno='Jan', vek=26, zeme='Norsko')
Metódy pre prácu s
NamedTuple
Trieda NamedTuple
obsahuje okrem iného nasledujúce
metódy:
make()
- umožňuje vytvoriť inštanciuNamedTuple
z iterovateľných objektov ako sú zoznamy alebo sekvencie,asdict()
- slúži na prevod na slovník,replace()
- vytvorí novú inštanciuNamedTuple
s rovnakým názvom, ale s novými hodnotami. Pôvodná inštanciaNamedTuple
zostáva nezmenená,fields
- slúži na získanie zoznamu názvov všetkých položiek v inštanciiNamedTuple
.
NamedTuple
často používa ako výkonný a jednoduchý
spôsob, ako organizovať a ukladať dáta, ktoré spája nejaký kontext, ale
nie sú k nim potrebné žiadne ďalšie metódy alebo funkcie.
DeQue
Trieda Deque
(skratka pre "Double-Ended Queue") predstavuje
špecifický typ frontu, ktorý je implementovaný ako dvojstranne otvorený
zoznam. To umožňuje efektívne pridávať a odoberať prvky z oboch strán. V
praxi sa DeQue
využíva napríklad pri riešení úloh s
BFS
(Breadth-First Search) a DFS
(Depth-First Search),
čo sú dva typy algoritmov pre hľadanie najkratšej cesty, hľadanie
všetkých ciest, hľadanie komponentov grafu a pod.
Príklad použitia DeQue
Použitie DeQue
v Pythone je veľmi jednoduché. Prvým naším
krokom bude importovať modul collections
. Potom vytvoríme
inštanciu triedy DeQue
a vypíšeme si ju:
from collections import deque deq = deque([1,2,3,4]) print(deq)
Výstupom v konzole bude:
Konzolová aplikácia
deque([1, 2, 3, 4])
Vyskúšajme si teraz, ako funguje naše tvrdenie o otvorených koncoch
zoznamu. Využijeme na to metódy append()
,
appendleft()
, pop()
a popleft()
:
deq.append(5) print(deq) deq.appendleft(0) print(deq) deq.pop() print(deq) deq.popleft() print(deq)
V konzole vidíme výsledok:
Konzolová aplikácia
deque([1, 2, 3, 4])
deque([1, 2, 3, 4, 5])
deque([0, 1, 2, 3, 4, 5])
deque([0, 1, 2, 3, 4])
deque([1, 2, 3, 4])
Pozrime sa teraz bližšie na to, čo kód vykonal:
- najprv sme vytvorili front
deq
s prvkami1
,2
,3
a4
, - pomocou metódy
append()
sme pridali prvok5
na koniec frontu, - pomocou metódy
appendleft()
sme pridali prvok0
na začiatok frontu, - pomocou metódy
pop()
sme odobrali posledný prvok z frontu, - pomocou metódy
popleft()
sme odobrali prvý prvok z frontu.
DeQue
Trieda DeQue
obsahuje okrem už uvedených aj nasledujúce
často využívané metódy:
clear()
- zmaže všetky prvky,count()
- vráti počet výskytov určitého prvku,extend()
- pridá viac prvkov na koniec,extendleft()
- pridá viac prvkov na začiatok,remove()
- odstráni prvok s určitou hodnotou,reverse()
- otočí poradie prvkov.
DeQue
oproti jednoduchému zoznamu je rýchlosť,
pretože pridávanie a odoberanie prvkov z oboch strán je v nej implementované
efektívne. Často sa používa ako zásobník alebo front, do ktorého je
možné prvky na jednu stranu pridávať az druhej strany ich odoberať.
To by bolo pre túto lekciu všetko.
V nasledujúcom kvíze, Kvíz - Komprehencie, Lambda, Chainmap a DeQue v Pythone, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.