Saviez-vous que Python possède des milliers de bibliothèques externes, mais que parmi elles se trouvent certains des outils les plus puissants déjà inclus dans la bibliothèque standard ?

Cette série a pour thème 'Approfondissement de la bibliothèque standard Python', où nous allons explorer une à une les bibliothèques standard souvent utilisées mais rarement abordées en profondeur.

Il ne s'agit pas simplement d'énumérer des fonctions, mais de comprendre les concepts à travers des exemples pratiques tout en développant vos compétences en application de code, afin d'élever votre maîtrise de Python à un niveau supérieur.


Utilisation avancée de collections : dépasser les bases pour des applications pratiques

1. Pourquoi commencer par collections ?

collections complète les types de données intégrés de Python (list, dict, tuple), tout en offrant des collections avancées très efficaces en termes de performance et de structure. Elles apparaissent souvent dans la pratique, mais ne sont pas souvent approfondies.

Dans cet article, nous allons nous concentrer sur cinq classes parmi les plus pratiques, en vous expliquant 'pourquoi les utiliser', 'comment les utiliser' et 'quand il est bon de les utiliser'.


2. Counter – l'art de compter les fréquences et au-delà

Comptez toutes les choses !

Concept de base

Le collections.Counter est l'une des classes très utiles incluses dans le module de la bibliothèque standard collections de Python. Comme son nom l'indique, il s'agit d'un "compteur", un dictionnaire spécial optimisé pour compter le nombre d'occurrences (fréquences) des données.

from collections import Counter

c = Counter(['a', 'b', 'c', 'a', 'b', 'a'])
print(c)  # Counter({'a': 3, 'b': 2, 'c': 1})

En insérant des objets itérables comme des listes, des chaînes de caractères ou des dictionnaires, cette structure de données compte combien de fois chaque élément apparaît.


Fonctionnalités principales et méthodes

📌 Méthodes d'initialisation variées

Le Counter peut être initialisé de plusieurs manières, permettant d'analyser les données avec flexibilité.

from collections import Counter

print(Counter(['a', 'b', 'a']))
# Counter({'a': 2, 'b': 1}) → Liste

print(Counter({'a': 2, 'b': 1}))
# Counter({'a': 2, 'b': 1}) → Dictionnaire

print(Counter(a=2, b=1))
# Counter({'a': 2, 'b': 1}) → Arguments nommés

📌 Accès aux éléments

Le Counter fonctionne comme un dict, mais renvoie 0 au lieu d'un KeyError si vous essayez d'accéder à une clé inexistante.

c = Counter('hello')
print(c['l'])  # 2 (le caractère 'l' apparaît 2 fois)
print(c['x'])  # 0 ('x' n'apparaît pas mais renvoie 0 au lieu d'une erreur)

📌 Ajout/modification d'éléments

Vous pouvez ajouter ou modifier directement des valeurs pour les éléments existants. Les clés inexistantes sont également ajoutées automatiquement.

c = Counter('hello')
c['l'] += 3
print(c)
# Counter({'l': 5, 'o': 1, 'h': 1, 'e': 1})

📌 most_common(n) – Extraction des éléments les plus fréquents

Retourne les n éléments sous forme de liste de tuples, triée par fréquence d'occurrence.

c = Counter('banana')
print(c.most_common(2))
# [('a', 3), ('n', 2)] → 'a' apparaît 3 fois, 'n' 2 fois

📌 elements() – un itérateur pour itérer sur les éléments

Fournit un itérateur qui répète les éléments en fonction des valeurs du compteur.

c = Counter('banana')
print(list(c.elements()))
# ['b', 'a', 'a', 'a', 'n', 'n']

Cependant, les éléments ayant une valeur inférieure à 0 ne sont pas inclus.


📌 Prise en charge des opérations mathématiques (opérations +, -, &, | entre Counters)

Une des forces du Counter est qu'il prend en charge les opérations arithmétiques et d'ensemble.

c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)

print(c1 + c2)
# Counter({'a': 4, 'b': 3}) → les mêmes clés sont additionnées

print(c1 - c2)
# Counter({'a': 2}) → les valeurs négatives sont ignorées, 'b' étant négatif est omis

print(c1 & c2)
# Counter({'a': 1, 'b': 1}) → intersection, selon la valeur minimale

print(c1 | c2)
# Counter({'a': 3, 'b': 2}) → union, selon la valeur maximale

Exemples d'applications pratiques

📌 Analyse de mots dans une chaîne
text = "the quick brown fox jumps over the lazy dog"
counter = Counter(text.split())
print(counter)
📌 Analyse de fréquence des logs
logs = ['INFO', 'ERROR', 'INFO', 'DEBUG', 'ERROR', 'ERROR']
print(Counter(logs))  # Counter({'ERROR': 3, 'INFO': 2, 'DEBUG': 1})
📌 Comptage des éléments dupliqués dans une liste
nums = [1, 2, 2, 3, 3, 3]
print(Counter(nums))  # Counter({3: 3, 2: 2, 1: 1})

Points à surveiller

  • Le Counter hérite de dict mais ne garantit pas l'ordre. Si l'ordre est nécessaire, il faut utiliser most_common().
  • Les éléments ne sont pas supprimés même si leur valeur tombe à 0 ou moins, et cela peut nécessiter un filtrage manuel.
c = Counter(a=3)
c.subtract({'a': 5})
print(c)  # Counter({'a': -2})  # Faites attention, même si la valeur tombe à 0 ou moins, l'élément ne disparaît pas.

Astuce : comment cumuler sans initialisation

counter = Counter()
with open("data.txt") as f:
    for line in f:
        counter.update(line.strip().split())

Conclusion

Le collections.Counter est un outil puissant qui est presque indispensable pour l'analyse de données, le traitement de logs, et le text mining. Pour les débutants, c'est un outil simple de comptage de fréquences, et pour les utilisateurs avancés, il peut évoluer en un outil de traitement avancé en combinant opérations et filtrages.


Aperçu du prochain épisode

  • defaultdict – Un monde sans KeyError, plus flexible que dict ! Restez à l'écoute pour le prochain numéro !

Comprendre en profondeur et utiliser correctement la bibliothèque standard améliorera indéniablement la qualité de votre code.