NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Lekce 8 - ChainMap, NamedTuple a DeQue v Pythonu

V minulé lekci, Komprehence, lambda výrazy a funkce v Pythonu, jsme si ukázali seznamové komprehence, lambda výrazy a některé vestavěné funkce pro práci s iterovatelnými objekty.

V tomto tutoriálu kolekcí v Pythonu se budeme věnovat třem jejich zástupcům. Konkrétně se zaměříme na třídy ChainMap, NamedTuple a Deque z modulu collections.

ChainMap

ChainMap je datový typ, který nám umožňuje sdružovat více slovníků do jednoho logického celku. Jinými slovy nám ChainMap umožňuje jednoduše a efektivně pracovat s více slovníky jako s jedním.

ChainMap se často používá v případě, když chceme hledat hodnotu pro klíč ve více slovnících. Velkou výhodou ChainMap je, že nám umožňuje udržovat všechny slovníky v jednom objektu. Hledání ve sdružených slovnících bude probíhat postupně v pořadí, v jakém byly uvedeny při vytvoření instance, dokud se pro klíč nenajde odpovídající hodnota.

Příklad použití ChainMap

Použití ChainMap v Pythonu je velmi jednoduché. Prvním krokem je importovat modul collections. Dále si nadefinujeme slovníky slovnik1 a slovnik2 a poté vytvoříme proměnnou mapa, která bude obsahovat instanci třídy ChainMap:

from collections import ChainMap

slovnik1 = {'a':1, 'b':2}
slovnik2 = {'c':3, 'b':4}

mapa = ChainMap(slovnik1, slovnik2)

Následně si vypíšeme obsah proměnné mapa a na dalším řádku výpis zopakujeme pro index ['b']:

print(mapa)
print(mapa['b'])

Výstupem v konzoli bude:

Konzolová aplikace
ChainMap({'a': 1, 'b': 2}, {'c': 3, 'b': 4})
2

Vidíme, že proměnná mapa se chová jako slovník, ve kterém jsou uloženy hodnoty ze slovnik1 a slovnik2. Následný výpis print(mapa['b']) vrací hodnotu klíče b z prvního slovníku, ve kterém je k dispozici, tj. ze slovnik1.

Nyní si vyzkoušíme obsah proměnné mapa modifikovat. Přidáme řádek s kódem mapa['c'] = 5. Tím přidáme do proměnné mapa nový klíč c s hodnotou 5. Tyto změny se projeví v proměnné mapa, ale ne v původních slovnících:

mapa['c'] = 5
print(mapa)

V konzoli tedy uvidíme:

Konzolová aplikace
ChainMap({'a': 1, 'b': 2, 'c': 5}, {'c': 3, 'b': 4})

Teď modifikujeme jeden ze slovníků a opět si vypíšeme obsah proměnné mapa:

slovnik2['c'] = 6
print(mapa)

Výstup v konzoli bude:

Konzolová aplikace
ChainMap({'a': 1, 'b': 2, 'c': 5}, {'c': 6, 'b': 4})

Vidíme, že hodnota klíče c se v proměnné mapa se změnila na 6, protože se na 6 změnila i v podkladovém slovníku (slovnik2['c'] = 6).

Metody pro práci s ChainMap

Třída ChainMap obsahuje mimo jiné následující metody:

  • maps - vrátí novou instance ChainMap, která přidá zadaný slovník (nebo slovníky) na konec seznamu slovníků,
  • new_child() - přidá nový slovník na první pozici v seznamu,
  • get(key[, default]) - vrátí hodnotu pro daný klíč. Pokud hodnota není nalezena, vrátí hodnotu default (pokud je zadána), jinak vyvolá výjimku KeyError,
  • keys() - vrátí seznam všech klíčů,
  • values() - vrátí seznam všech hodnot,
  • items() - vrátí seznam všech položek ve formátu (klíč, hodnota).

Výše uvedené si tedy shrneme. Platí, že ChainMap je aktualizovatelný pohled nad více slovníky. Hodnoty v příslušné instanci se mění v závislosti na změnách v jednotlivých podkladových slovnících.

NamedTuple

Třída NamedTuple je speciální případ neseřazeného datového typu, který kombinuje výhody tuple a slovníku. Stejně jako tuple má také pevnou délku a její instance nelze modifikovat. Zásadní rozdíl ale spočívá v tom, že jednotlivé položky mohou být přístupné pomocí jména (stejně jako v případě slovníku).

Výhodou NamedTuple tedy je, že umožňuje jasnější a čitelnější kód, protože jména položek jsou přímo součástí kódu. Díky pevné délce je také efektivnější než použití slovníku.

Příklad použití NamedTuple

NamedTuple se vytváří pomocí funkce namedtuple(). Nejprve si třídu NamedTuple naimportujeme z modulu collections. Poté pomocí funkce namedtuple() vytvoříme třídu Osoba, která rozšiřuje NamedTuple o položky jmeno, prijmeni a vek. Následně vytvoříme proměnnou student, v níž bude instance třídy Osoba:

from collections import namedtuple

Osoba = namedtuple("Osoba", ["jmeno", "prijmeni", "vek"])
student = Osoba("Jan", "Novák", 26)

K položkám NamedTuple pak budeme přistupovat pomocí jména položky jako atributu instance, jako by šlo o obyčejné atributy třídy:

print("Jméno a příjmení studenta: "+ student.jmeno + " " + student.prijmeni)
print("Věk studenta:", student.vek)

V konzoli vidíme výstup:

Konzolová aplikace
Jméno a příjmení studenta: Jan Novák
Věk studenta: 26

Následujícím způsobem pak vypíšeme celou instanci NamedTuple z proměnné turista:

from collections import namedtuple

Turista = namedtuple('Turista', ['jmeno', 'vek', 'zeme'])
turista = Turista('Jan', 26, 'Norsko')

print(turista)

Výstupem v konzoli bude:

Konzolová aplikace
Turista(jmeno='Jan', vek=26, zeme='Norsko')

Metody pro práci s NamedTuple

Třída NamedTuple obsahuje mimo jiné následující metody:

  • make() - umožňuje vytvořit instanci NamedTuple z iterovatelných objektů jako jsou seznamy nebo sekvence,
  • asdict() - slouží k převodu na slovník,
  • replace() - vytvoří novou instanci NamedTuple se stejným názvem, ale s novými hodnotami. Původní instance NamedTuple zůstává nezměněná,
  • fields - slouží k získání seznamu názvů všech položek v instanci NamedTuple.

V praxi se NamedTuple často používá jako výkonný a jednoduchý způsob, jak organizovat a ukládat data, která spojuje nějaký kontext, ale nejsou k nim třeba žádné další metody nebo funkce.

DeQue

Třída Deque (zkratka pro "Double-Ended Queue") představuje specifický typ fronty, který je implementovaný jako dvoustranně otevřený seznam. To umožňuje efektivně přidávat a odebírat prvky z obou stran. V praxi se DeQue využívá například při řešení úloh s BFS (Breadth-First Search) a DFS (Depth-First Search), což jsou dva typy algoritmů pro hledání nejkratší cesty, hledání všech cest, hledání komponent grafu apod.

Příklad použití DeQue

Použití DeQue v Pythonu je velmi jednoduché. Prvním naším krokem bude importovat modul collections. Poté vytvoříme instanci třídy DeQue a vypíšeme si ji:

from collections import deque

deq = deque([1,2,3,4])
print(deq)

Výstupem v konzoli bude:

Konzolová aplikace
deque([1, 2, 3, 4])

Vyzkoušejme si teď, jak funguje naše tvrzení o otevřených koncích seznamu. Využijeme k tomu metody append(), appendleft(), pop() a popleft():

deq.append(5)
print(deq)

deq.appendleft(0)
print(deq)

deq.pop()
print(deq)

deq.popleft()
print(deq)

V konzoli vidíme výsledek:

Konzolová aplikace
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])

Podívejme se teď blíže na to, co kód vykonal:

  • nejprve jsme vytvořili frontu deq s prvky 1, 2, 3 a 4,
  • pomocí metody append() jsme přidali prvek 5 na konec fronty,
  • pomocí metody appendleft() jsme přidali prvek 0 na začátek fronty,
  • pomocí metody pop() jsme odebrali poslední prvek z fronty,
  • pomocí metody popleft() jsme odebrali první prvek z fronty.

Metody pro práci s DeQue

Třída DeQue obsahuje kromě už uvedených také následující často využívané metody:

  • clear()- smaže všechny prvky,
  • count()- vrátí počet výskytů určitého prvku,
  • extend()- přidá více prvků na konec,
  • extendleft()- přidá více prvků na začátek,
  • remove()- odstraní prvek s určitou hodnotou,
  • reverse() - otočí pořadí prvků.

Výhodou DeQue oproti prostému seznamu je rychlost, protože přidávání a odebírání prvků z obou stran je v ní implementováno efektivně. Často se používá jako zásobník nebo fronta, do které lze prvky na jednu stranu přidávat a z druhé strany je odebírat.

To by bylo pro tuto lekci vše.

V následujícím kvízu, Kvíz - Komprehence, Lambda, Chainmap a DeQue v Pythonu, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.


 

Předchozí článek
Komprehence, lambda výrazy a funkce v Pythonu
Všechny články v sekci
Kolekce v Pythonu
Přeskočit článek
(nedoporučujeme)
Kvíz - Komprehence, Lambda, Chainmap a DeQue v Pythonu
Článek pro vás napsal arnie
Avatar
Uživatelské hodnocení:
281 hlasů
.
Aktivity