Cours de Python / Utiliser les ensembles pour l’unicité et les opérations ensemblistes

Un ensemble Python, de type set, conserve des éléments hachables uniques et permet de tester leur présence ou de comparer deux collections. Le passage à un ensemble supprime les occurrences répétées et l’information de position : vérifiez que ces informations peuvent être perdues avant la conversion.

Créer un ensemble et lire ses opérations

Un ensemble non vide peut s’écrire {"food", "books"}. Pour un ensemble vide, utilisez set() : {} crée un dictionnaire. Un set n’a pas d’index comme une liste, et son ordre de parcours ne doit pas servir de règle d’affichage. Les listes et les dictionnaires ne sont pas hachables et ne peuvent donc pas être ses éléments.

Expression Résultat recherché
a | b Union : éléments présents dans au moins un ensemble
a & b Intersection : éléments communs
a - b Éléments de a absents de b
a ^ b Éléments présents dans un seul des deux ensembles

La différence a - b est orientée : intervertir les deux ensembles change la question. Le contrat des éléments hachables est le même que pour les clés de dictionnaire. La référence de set et frozenset détaille ces opérations et les méthodes de modification.

Comparer les catégories utilisées et autorisées

Python 3 et sa bibliothèque standard suffisent. Enregistrez le bloc complet suivant dans sets.py, en UTF-8, dans un dossier d’exercice. Depuis un terminal ouvert dans ce dossier avec l’environnement virtuel du projet activé, lancez python sets.py. Sur macOS ou Ubuntu hors environnement virtuel, utilisez python3 si c’est le nom de votre interpréteur.

used = {"food", "transport", "food"}
allowed = {"food", "books"}
print(sorted(used))
print(sorted(used & allowed))
print(sorted(used - allowed))
used.discard("missing")
print("food" in used)

La sortie attendue est :

['food', 'transport']
['food']
['transport']
True

used contient les catégories rencontrées et allowed les catégories autorisées. food signifie « alimentation », transport « transport » et books « livres ». food est écrit deux fois dans le premier littéral, mais ne produit qu’un membre. L’intersection retient food ; la différence used - allowed révèle transport comme catégorie non autorisée.

Chaque sorted produit une liste triée pour stabiliser l’affichage. L’ensemble lui-même ne devient pas une séquence triée. La suppression facultative de missing ne change rien ici, puis le test d’appartenance confirme la présence de food avec True.

Distinguer unicité, ordre et transactions répétées

Pour des éléments hachables dont on veut garder la première occurrence dans l’ordre, list(dict.fromkeys(items)) peut convenir. Les répétitions et leurs nombres disparaissent tout de même. Si leur fréquence compte, conservez les occurrences d’origine et calculez séparément leurs effectifs.

Deux paiements du même montant peuvent représenter deux transactions distinctes. Pour [8000, 8000], la somme est 16000 ; convertir les montants en set ne laisse que 8000. Supprimer des valeurs égales n’est donc pas une vérification de doublons de transaction.

Si votre règle concerne des identifiants de transaction, vérifiez ces identifiants. Définissez ensuite le traitement d’un identifiant déjà rencontré : signaler une erreur, ignorer une répétition autorisée ou mettre à jour un enregistrement. Une conversion en set ne prend pas cette décision et peut masquer une entrée incorrecte.

Choisir le comportement de suppression et restaurer les essais

remove() lève une KeyError si l’élément demandé manque ; discard() accepte cette absence. Si un élément doit obligatoirement exister, remove peut révéler une condition non respectée. Pour un nettoyage facultatif, discard exprime que l’absence est acceptable.

  1. Ajoutez temporairement used.add("food") après la définition de used. Sa taille reste 2 et les sorties ne changent pas : food était déjà présent.
  2. Ajoutez ensuite used.add("books"). La première liste triée devient ['books', 'food', 'transport'], et l’intersection devient ['books', 'food']. La différence reste transport.
  3. Retirez ces deux appels pour retrouver le programme initial. Remplacez seulement used.discard("missing") par used.remove("missing") : une KeyError interrompt le programme avant la dernière ligne True.
  4. Rétablissez discard et relancez l’exemple complet pour vérifier les quatre lignes attendues.

Choisissez une liste quand l’ordre et les répétitions comptent, un tuple pour une petite structure de positions fixes, un dictionnaire pour retrouver des valeurs par des noms et un ensemble pour l’unicité et l’appartenance. La structure choisie doit conserver les informations dont le traitement a réellement besoin.