Leçons du module (3/4)
collections : Counter et defaultdict
Le module collections ajoute des types de données spécialisés qui étendent les collections intégrées. Les trois plus utilisés : Counter, defaultdict, namedtuple.
Counter : comptage des fréquences
from collections import Counter
parole = ["mela", "pera", "mela", "kiwi", "mela", "pera"]
c = Counter(parole)
# Counter({'mela': 3, 'pera': 2, 'kiwi': 1})
c["mela"] # 3
c["banana"] # 0 (default for missing keys, NO KeyError)
c.most_common(2) # [('mela', 3), ('pera', 2)]Il fonctionne également sur les chaînes (compte les caractères) :
Counter("ciao mondo")
# Counter({'o': 2, 'c': 1, 'i': 1, 'a': 1, ' ': 1, 'm': 1, 'n': 1, 'd': 1})Il prend en charge les opérations de type ensemble sur les nombres (+, -, &, |) — très pratique pour agréger les totaux provenant de différentes sources.
defaultdict : dictionnaire avec valeur par défaut automatique
Un dictionnaire qui, lorsque vous accédez à une clé manquante, la crée en appelant une fabrique.
from collections import defaultdict
gruppi = defaultdict(list) # factory = list (empty list)
for nome in ["Ada", "Linus", "Ada", "Grace"]:
gruppi[nome].append(1)
# defaultdict(list, {'Ada': [1, 1], 'Linus': [1], 'Grace': [1]})Sans defaultdict, vous devriez écrire :
gruppi = {}
for nome in [...]:
if nome not in gruppi:
gruppi[nome] = []
gruppi[nome].append(1)Fabriques courantes : list, int (par défaut 0), set, dict.
namedtuple : tuples avec noms de champs
Un moyen léger de créer des classes d'enregistrements immuables. C'est un tuple, mais avec un accès aux champs par nom.
from collections import namedtuple
Punto = namedtuple("Punto", ["x", "y"])
p = Punto(3, 4)
p.x # 3 (access by name)
p[0] # 3 (access by index, still a tuple)
p.x + p.y # 7
# typical use: return multiple values from a function
def divisione(a, b):
Risultato = namedtuple("Risultato", ["quoziente", "resto"])
return Risultato(a // b, a % b)
r = divisione(17, 5)
r.quoziente # 3
r.resto # 2(Pour des cas plus complexes, il existe également dataclasses depuis la version 3.7 — voir M9.)
namedtuple : enregistrements immuables légers
Le module collections exporte également namedtuple, qui vous permet de créer rapidement de légers objets similaires à des classes pour stocker des données structurées sans écrire de constructeurs ou de méthodes répétitives :
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y)À vous de jouer
Étant donné la liste `words = ['mela', 'pera', 'mela', 'kiwi', 'mela', 'pera']`, calculez le mot le plus fréquent sous forme de chaîne dans `top`. Évaluez `top`.
Afficher l'indice
Counter(...).most_common(1) renvoie [(mot, compte)].
Solution disponible après 3 tentatives
Exercice de révision
Étant donné les étudiants `enrollments = [('Ada', 'mate'), ('Linus', 'fisica'), ('Ada', 'storia'), ('Grace', 'mate')]`, créez `courses_per_student` sous forme de defaultdict(list). Évaluez `dict(courses_per_student)`.
Afficher l'indice
defaultdict(list) puis for s, c in enrollments.
Solution disponible après 3 tentatives
Défi supplémentaire
Importez `Counter` depuis `collections`. Comptez la fréquence des caractères dans la chaîne `text = "abracadabra"`. Stockez le compteur dans `char_counter` et évaluez-le.
Afficher l'indice
Counter prend la chaîne en paramètre et compte les occurrences de chaque lettre.
Solution disponible après 3 tentatives