Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

5. diel - ChainMap, NamedTuple a DeQue v Pythone

V predchádzajúcom kvíze, Kvíz - Tuples, stock, slovníky a zoznamy v Pythone, sme si overili nadobudnuté skúsenosti z predchádzajúcich lekcií.

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štanciu ChainMap, 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ýnimku KeyError,
  • 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).
Vyššie uvedené si teda zhrnieme. Platí, že 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štanciu NamedTuple z iterovateľných objektov ako sú zoznamy alebo sekvencie,
  • asdict() - slúži na prevod na slovník,
  • replace() - vytvorí novú inštanciu NamedTuple s rovnakým názvom, ale s novými hodnotami. Pôvodná inštancia NamedTuple zostáva nezmenená,
  • fields - slúži na získanie zoznamu názvov všetkých položiek v inštancii NamedTuple.
V praxi sa 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 prvkami 1, 2, 3 a 4,
  • pomocou metódy append() sme pridali prvok 5 na koniec frontu,
  • pomocou metódy appendleft() sme pridali prvok 0 na začiatok frontu,
  • pomocou metódy pop() sme odobrali posledný prvok z frontu,
  • pomocou metódy popleft() sme odobrali prvý prvok z frontu.
Metódy pre prácu s 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.
Výhodou 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 ďalšej lekcii, Iterátory druhýkrát: Generátory , si vytvoríme vlastný iterátor, zoznámime sa s generátormi a preskúmame ich výhody.


 

Predchádzajúci článok
Kvíz - Tuples, stock, slovníky a zoznamy v Pythone
Všetky články v sekcii
Kolekcia v Pythone
Preskočiť článok
(neodporúčame)
Iterátory druhýkrát: Generátory
Článok pre vás napísal Ondřej Tom
Avatar
Užívateľské hodnotenie:
1 hlasov
a
Aktivity