Cum să utilizați contorul Python din modulul Colecții

În acest ghid, vei descoperi cum să folosești obiectul contor din modulul `collections` al limbajului Python.

Când analizezi secvențe ample în Python, cum ar fi listele sau șirurile, uneori este esențial să reții elementele care apar și frecvența lor.

Un dicționar Python este o structură de date fundamentală excelentă pentru astfel de situații. Cu toate acestea, clasa `Counter` din modulul `collections` oferă o soluție mai simplă, creând un contor – un fel de dicționar care asociază elementele cu numărul lor de apariții într-o secvență.

În următoarele minute, vei învăța cum:

  • Să utilizezi obiectul contor al limbajului Python
  • Să construiești un dicționar Python pentru a stoca frecvențele elementelor dintr-o structură iterabilă
  • Să rescrii acest dicționar folosind contorul Python, printr-o sintaxă mai directă
  • Să efectuezi operații precum actualizarea și scăderea elementelor, precum și identificarea intersecției dintre două obiecte contor
  • Să accesezi cele mai frecvente elemente dintr-un contor prin metoda `most_common()`.

Să începem explorarea!

Modulul `collections` și clasa `Counter` din Python

Un dicționar Python este adesea utilizat pentru a stoca elementele dintr-o structură iterabilă și frecvența lor. Elementele sunt stocate ca și chei, iar numărul lor de apariții ca valori corespunzătoare.

Fiindcă clasa `Counter` face parte din modulul `collections` integrat în Python, o poți importa în codul tău astfel:

from collections import Counter

Odată importată, poți crea o instanță a obiectului contor așa:

<obiect_contor> = Counter(iterabil)

Unde:

  • `iterabil` reprezintă orice structură iterabilă validă în Python, cum ar fi o listă, un șir sau un tuplu.
  • Elementele din `iterabil` trebuie să fie „hashable” (adică, imuabile și utilizabile ca chei într-un dicționar).

Acum, că știm cum să folosim `Counter` pentru a crea obiecte contor din diverse structuri iterabile, să trecem la exemple concrete.

Codul folosit în acest ghid este disponibil pe GitHub.

Cum creezi un obiect contor din structuri iterabile Python

Să creăm un șir, de exemplu „reîntrupare”, și să-l numim `cuvânt`.

>>> cuvânt = "reîntrupare"

Scopul este să construim un dicționar în care fiecare literă din șirul `cuvânt` este asociată cu numărul de apariții în șir. O modalitate de a face asta este prin bucle `for`, ca mai jos:

>>> număr_litere = {}
>>> for literă in cuvânt:
...     if literă not in număr_litere:
...         număr_litere[literă] = 0
...     număr_litere[literă] += 1
...
>>> număr_litere
{'r': 2, 'e': 2, 'î': 1, 'n': 1, 't': 1, 'u': 1, 'p': 1, 'a': 1}

Analizăm pașii din codul de mai sus:

  • Inițializăm `număr_litere` ca un dicționar gol.
  • Parcurgem șirul `cuvânt`.
  • Verificăm dacă litera curentă există deja în dicționarul `număr_litere`.
  • Dacă litera nu este în dicționar, o adăugăm cu valoarea inițială 0 și apoi incrementăm valoarea cu 1.
  • Pentru fiecare apariție a literei în `cuvânt`, valoarea corespunzătoare este mărită cu 1.
  • Acest proces continuă până la parcurgerea completă a șirului.

Am construit dicționarul `număr_litere` – manual – folosind o buclă `for` pentru a itera prin `cuvânt`.

Acum, hai să folosim clasa `Counter` din modulul `collections`. E suficient să transmitem șirul `cuvânt` funcției `Counter()` pentru a obține `număr_litere`, fără a mai fi nevoie de bucle:

>>> from collections import Counter
>>> număr_litere = Counter(cuvânt)
>>> număr_litere
Counter({'r': 2, 'e': 2, 'î': 1, 'n': 1, 't': 1, 'u': 1, 'p': 1, 'a': 1})

Un obiect contor este de fapt tot un dicționar Python. Putem verifica acest lucru prin funcția `isinstance()`:

>>> isinstance(număr_litere, dict)
True

După cum se vede, `isinstance(număr_litere, dict)` returnează `True`, indicând că obiectul contor `număr_litere` este într-adevăr o instanță a clasei `dict`.

Modificarea obiectului contor

Până acum, am învățat să creăm obiecte contor din șiruri.

Obiectele contor pot fi și modificate, adăugând elemente dintr-o altă structură iterabilă, sau eliminând elemente din acestea.

Actualizarea unui contor cu elemente dintr-o altă structură iterabilă

Să inițializăm un alt șir, `alt_cuvânt`:

>>> alt_cuvânt = "inefabil"

Presupunem că vrem să adăugăm elementele din `alt_cuvânt` la `număr_litere`.

Putem folosi metoda `update()` pe obiectul contor `număr_litere`:

>>> număr_litere.update(alt_cuvânt)
>>> număr_litere
Counter({'e': 3, 'r': 2, 'a': 2, 'i': 2, 'n': 2, 'î': 1, 't': 1, 'u': 1, 'p': 1, 'b': 1, 'l': 1, 'f': 1})

Rezultatul indică că obiectul contor a fost modificat și include acum frecvențele de apariție ale literelor din `alt_cuvânt`.

Scăderea elementelor dintr-o altă structură iterabilă

Acum, să scădem valoarea lui `alt_cuvânt` din obiectul `număr_litere`. Pentru asta, folosim metoda `subtract()`. Sintaxa `<obiect-contor>.subtract(<structura-iterabilă>)` scade valorile corespunzătoare elementelor din structura dată, din `<obiect-contor>`.

Să scădem `alt_cuvânt` din `număr_litere`:

>>> număr_litere.subtract(alt_cuvânt)
>>> număr_litere
Counter({'r': 2, 'e': 2, 'î': 1, 't': 1, 'u': 1, 'p': 1, 'a': 0, 'n': 0, 'b': 0, 'l': 0, 'f': 0, 'i': 0})

Vedem că valorile corespunzătoare literelor din `alt_cuvânt` au fost scăzute, dar literele adăugate „b”, „l” și „f” nu sunt șterse. Valoarea lor este acum 0.

Notă: Aici am folosit `alt_cuvânt`, un șir, în apelul metodei `subtract()`. Putem folosi și un alt obiect contor sau orice altă structură iterabilă.

Intersecția dintre două obiecte contor în Python

Uneori poate fi util să afli intersecția dintre două obiecte contor, adică elementele comune.

Să creăm un alt contor, numit `număr_litere_2`, din șirul `alt_cuvânt`, adică „inefabil”:

>>> alt_cuvânt = "inefabil"
>>> număr_litere_2 = Counter(alt_cuvânt)
>>> număr_litere_2
Counter({'i': 2, 'e': 1, 'n': 1, 'f': 1, 'a': 1, 'b': 1, 'l': 1})

Putem folosi operatorul `&` pentru a calcula intersecția dintre `număr_litere` și `număr_litere_2`:

>>> număr_litere & număr_litere_2
Counter({'e': 1})

Observăm că obținem literele comune și frecvența lor. Atât „reîntrupare” cât și „inefabil” au o apariție a lui „e” în comun.

Aflarea celor mai frecvente elemente folosind `most_common`

O altă operație utilă pe obiectul contor este identificarea elementelor care apar cel mai des.

Pentru a obține primele `k` elemente cele mai frecvente, se poate folosi metoda `most_common()` pe contor. Apelăm `most_common()` pe `număr_litere` pentru a găsi cele 3 litere care apar cel mai des.

>>> număr_litere.most_common(3)
[('r', 2), ('e', 2), ('î', 1)]

Vedem că literele „r” și „e” apar de două ori, iar „î” o singură dată în cuvântul „reîntrupare”.

Această operație este utilă în special dacă un contor are multe înregistrări și te interesează doar cele mai comune.

Concluzii

Iată o recapitulare a ceea ce am învățat:

  • Clasa `Counter` din modulul `collections` al Python este folosită pentru a obține un dicționar cu frecvențele tuturor elementelor dintr-o structură iterabilă. Elementele structurii trebuie să fie „hashable”.
  • Poți actualiza un contor folosind conținutul unui alt contor sau o structură iterabilă, prin metoda `update()` cu sintaxa: `contor1.update(contor2)`. Poți folosi orice structură iterabilă în loc de `contor2`.
  • Dacă vrei să scazi frecvențele unui set de elemente, poți folosi `subtract()`: `contor1.subtract(contor2)`.
  • Pentru a găsi elementele comune a două contoare, folosește operatorul `&`. Pentru contoarele `contor1` și `contor2`, expresia `contor1 & contor2` returnează intersecția lor.
  • Pentru a accesa primele `k` elemente cele mai frecvente dintr-un contor, folosește metoda `most_common()`. `contor.most_common(k)` returnează o listă cu cele mai frecvente `k` elemente și frecvența lor.

Următorul pas este să descoperi cum se utilizează `defaultdict`, o altă clasă din modulul `collections`. Poți folosi `defaultdict` în loc de un dicționar Python obișnuit pentru a gestiona cheile lipsă.