V tomto návodu se ponoříme do světa objektu čítače, který je součástí modulu `collections` v Pythonu.
Při práci s rozsáhlými sekvencemi dat, jako jsou seznamy nebo řetězce, se často setkáme s potřebou zaznamenat výskyt jednotlivých prvků a frekvenci jejich opakování.
Pythonovský slovník je standardní datovou strukturou pro takové úkoly. Třída `Counter` z modulu `collections` však tento proces usnadňuje. Vytvoří se čítač, což je v podstatě slovník, kde klíči jsou prvky sekvence a hodnoty udávají, kolikrát se daný prvek v sekvenci objevil.
Během chvíle se dozvíte:
- Jak efektivně používat objekt čítače v Pythonu.
- Jak ručně vytvořit slovník pro evidenci četnosti výskytu prvků v iterovatelném objektu.
- Jak zjednodušit tento proces s využitím třídy `Counter`.
- Jak provádět operace, jako je aktualizace, odečítání prvků a hledání průniku mezi dvěma čítači.
- Jak s metodou `most_common()` získat nejčastější položky v čítači.
Pusťme se do toho!
Modul Python `collections` a třída `Counter`
Pro uložení prvků a jejich četnosti v iterovatelné struktuře se standardně používá slovník Pythonu. V tomto případě jsou prvky klíči a počty výskyty hodnotami.
Třída `Counter` je součástí vestavěného modulu `collections`, takže je třeba ji importovat do vašeho skriptu:
from collections import Counter
Po importu můžete vytvořit instanci objektu čítače:
<objekt_citace> = Counter(iterovatelný_objekt)
Kde:
- `iterovatelný_objekt` je libovolný platný iterovatelný objekt v Pythonu, jako seznam, řetězec nebo n-tice.
- Prvky v iterovatelném objektu musí být hashovatelné.
Nyní, když rozumíme, jak používat `Counter` k vytvoření čítače z libovolného iterovatelného objektu, začneme kódovat. Příklady z tohoto návodu najdete na GitHubu.
Jak vytvořit objekt `Counter` z iterovatelných objektů
Začněme s řetězcem, například „renaissance“, který si uložíme do proměnné `slovo`.
>>> slovo = "renaissance"
Naším cílem je vytvořit slovník, kde bude každé písmeno v řetězci mapováno na počet jeho výskytů. Jednou z možností je použití cyklu `for`:
>>> cetnost_pismen = {} >>> for pismeno in slovo: ... if pismeno not in cetnost_pismen: ... cetnost_pismen[pismeno] = 0 ... cetnost_pismen[pismeno] += 1 ... >>> cetnost_pismen {'r': 1, 'e': 2, 'n': 2, 'a': 2, 'i': 1, 's': 2, 'c': 1}
Pojďme si rozebrat, co se děje ve výše uvedeném kódu:
- Inicializujeme `cetnost_pismen` jako prázdný slovník.
- Procházíme řetězec `slovo`.
- Zkontrolujeme, zda je písmeno přítomno ve slovníku `cetnost_pismen`.
- Pokud písmeno není přítomno, přidáme ho s hodnotou 0 a poté ji navýšíme o 1.
- Pro každý výskyt písmene ve slově se hodnota příslušného klíče navýší o 1.
- Proces pokračuje, dokud se neprojdou všechna písmena.
Vytvořili jsme tedy slovník četnosti písmen ručně pomocí cyklu `for`. Nyní použijeme třídu `Counter` z modulu `collections`. Stačí předat řetězec `slovo` do `Counter()`, abychom získali stejný výsledek bez nutnosti iterovat.
>>> from collections import Counter >>> cetnost_pismen = Counter(slovo) >>> cetnost_pismen Counter({'e': 2, 'n': 2, 'a': 2, 's': 2, 'r': 1, 'i': 1, 'c': 1})
Objekt čítače je také slovník. Můžeme to ověřit pomocí funkce `isinstance()`:
>>> isinstance(cetnost_pismen,dict) True
Jak vidíte, `isinstance(cetnost_pismen, dict)` vrací `True`, což dokazuje, že objekt čítače `cetnost_pismen` je instancí třídy `dict`.
Úpravy objektu `Counter`
Zatím jsme se naučili vytvářet objekty čítače z řetězců. Objekty čítače se dají modifikovat aktualizací o prvky z jiného iterovatelného objektu nebo odečtením jiného iterovatelného objektu.
Aktualizace čítače s prvky z jiného iterovatelného objektu
Inicializujeme si nový řetězec `dalsi_slovo`:
>>> dalsi_slovo = "effervescence"
Řekněme, že chceme aktualizovat objekt čítače `cetnost_pismen` o prvky z řetězce `dalsi_slovo`.
Můžeme použít metodu `update()` na objektu čítače `cetnost_pismen`.
>>> cetnost_pismen.update(dalsi_slovo) >>> cetnost_pismen Counter({'e': 7, 'n': 3, 's': 3, 'c': 3, 'r': 2, 'a': 2, 'f': 2, 'i': 1, 'v': 1})
Výstup ukazuje, že objekt čítače byl aktualizován o písmena z `dalsi_slovo` a jejich počet výskytů.
Odečítání prvků z jiného iterovatelného objektu
Nyní odečteme hodnotu `dalsi_slovo` z objektu `cetnost_pismen`. K tomu použijeme metodu `subtract()`. Použitím `
Odečteme `dalsi_slovo` z `cetnost_pismen`:
>>> cetnost_pismen.subtract(dalsi_slovo) >>> cetnost_pismen Counter({'e': 2, 'n': 2, 'a': 2, 's': 2, 'r': 1, 'i': 1, 'c': 1, 'f': 0, 'v': 0})
Je vidět, že hodnoty odpovídající písmenům v `dalsi_slovo` byly odečteny, ale klíče ‚f‘ a ‚v‘ nebyly odstraněny. Nyní se mapují na hodnotu 0.
Poznámka: Zde jsme předali `dalsi_slovo` jako řetězec. Můžeme ale také předat objekt čítače nebo jiný iterovatelný objekt.
Průnik mezi dvěma objekty `Counter` v Pythonu
Občas můžete potřebovat najít průnik mezi dvěma objekty čítače, abyste zjistili, které klíče mají společné.
Vytvořme si nový objekt čítače, například `cetnost_2`, z řetězce „effervescence“.
>>> dalsi_slovo = "effervescence" >>> cetnost_2 = Counter(dalsi_slovo) >>> cetnost_2 Counter({'e': 5, 'f': 2, 'c': 2, 'r': 1, 'v': 1, 's': 1, 'n': 1})
Můžeme použít operátor `&` pro nalezení průniku mezi `cetnost_pismen` a `cetnost_2`.
>>> cetnost_pismen & cetnost_2 Counter({'e': 2, 'r': 1, 'n': 1, 's': 1, 'c': 1})
Všimněte si, že získáme společné klíče a počet jejich výskytů. Jak „renaissance“ tak „effervescence“ obsahují dva výskyty „e“ a jeden společný výskyt „r“, „n“, „s“ a „c“.
Hledání nejčastějších položek pomocí `most_common`
Další běžnou operací je hledání nejčastěji se vyskytujících položek v objektu čítače.
Můžete použít metodu `most_common()` na objektu čítače pro získání n nejčastějších položek. Zde zavoláme `most_common()` na `cetnost_pismen`, abychom našli tři nejčastější písmena.
>>> cetnost_pismen.most_common(3) [('e', 2), ('n', 2), ('a', 2)]
Je vidět, že písmena „e“, „n“ a „a“ se ve slově „renaissance“ vyskytují dvakrát.
To je velmi užitečné, pokud čítač obsahuje velké množství dat a vy chcete pracovat s nejčastějšími klíči.
Závěr
Zde je stručný přehled, co jsme se naučili:
- Třída `Counter` z modulu `collections` se používá k vytvoření slovníku, kde klíče jsou prvky z libovolného iterovatelného objektu a hodnoty udávají jejich četnost výskytu. Ujistěte se, že všechny prvky v iterovatelném objektu jsou hashovatelné.
- Obsah jednoho objektu čítače se dá aktualizovat o obsah jiného objektu čítače nebo jiného iterovatelného objektu pomocí metody `update()`, syntaxí: `citač1.update(citač2)`. Namísto `citač2` můžete použít libovolný iterovatelný objekt.
- Pokud chcete odstranit obsah jedné iterovatelné položky z aktualizovaného čítače, můžete použít metodu `subtract()`: `citač1.subtract(citač2)`.
- Pro nalezení společných prvků mezi dvěma objekty čítače můžete použít operátor `&`. Pokud máte dva čítače `citač1` a `citač2`, tak `citač1 & citač2` vrací jejich průnik.
- Pro získání `k` nejčastějších položek v čítači můžete použít metodu `most_common()`. `counter.most_common(k)` vrátí `k` nejčastějších položek a jejich četnosti.
Doporučujeme vám dále prozkoumat třídu `defaultdict` z modulu `collections`, která je užitečná pro zpracování chybějících klíčů a představuje alternativu ke standardním slovníkům Pythonu.