Jak používat Pythonův čítač z modulu Kolekce

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 `.subtract()` se odečtou hodnoty odpovídající prvkům v `` od ``.

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.