couleurs = {"rouge", "vert", "bleu"}
nombres = {1, 2, 3, 4, 5}
print(couleurs)
print(nombres)
print(type(couleurs)){'bleu', 'rouge', 'vert'}
{1, 2, 3, 4, 5}
<class 'set'>
Les ensembles (set en Python) sont des collections sans doublons et non ordonnées. Moins connus que les listes et dicts, ils sont pourtant extrêmement utiles pour deux cas : supprimer les doublons et faire des opérations ensemblistes (union, intersection, différence). Le TOSA les teste surtout sur ces deux usages.
Un ensemble est une collection d’éléments uniques et non ordonnés. On le crée avec des accolades {} comme un dictionnaire, mais sans paires clé: valeur.
couleurs = {"rouge", "vert", "bleu"}
nombres = {1, 2, 3, 4, 5}
print(couleurs)
print(nombres)
print(type(couleurs)){'bleu', 'rouge', 'vert'}
{1, 2, 3, 4, 5}
<class 'set'>
Quatre caractéristiques :
s = {1, 2, 2, 3, 3, 3, 4}
print(s) # {1, 2, 3, 4}{1, 2, 3, 4}
s = {10, 20, 30}
print(s[0])--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[3], line 2 1 s = {10, 20, 30} ----> 2 print(s[0]) TypeError: 'set' object is not subscriptable
{} crée un dictionnaire vide, pas un ensemble vide ! Pour un ensemble vide, il faut utiliser set() :
dict_vide = {}
ens_vide = set()
print(type(dict_vide))
print(type(ens_vide))<class 'dict'>
<class 'set'>
# Depuis une liste (supprime les doublons automatiquement)
nombres = set([1, 2, 2, 3, 3, 4])
print(nombres)
# Depuis une chaîne (supprime les doublons de caractères)
lettres = set("banana")
print(lettres){1, 2, 3, 4}
{'b', 'a', 'n'}
| Méthode | Effet |
|---|---|
add(x) |
Ajoute x (sans effet si déjà présent) |
remove(x) |
Retire x, lève KeyError si absent |
discard(x) |
Retire x, pas d’erreur si absent |
pop() |
Retire et renvoie un élément arbitraire |
clear() |
Vide l’ensemble |
s = {1, 2, 3}
s.add(4)
print(s)
s.add(2) # déjà présent : sans effet
print(s)
s.remove(1)
print(s)
s.discard(99) # pas d'erreur même si absent
print(s){1, 2, 3, 4}
{1, 2, 3, 4}
{2, 3, 4}
{2, 3, 4}
remove vs discard
s = {1, 2, 3}
s.remove(99) # KeyError : 99--------------------------------------------------------------------------- KeyError Traceback (most recent call last) Cell In[7], line 2 1 s = {1, 2, 3} ----> 2 s.remove(99) # KeyError : 99 KeyError: 99
s = {1, 2, 3}
s.discard(99) # pas d'erreur
print(s){1, 2, 3}
Si vous ne savez pas si l’élément est présent, préférez discard.
inLe test in est extrêmement rapide sur un set (complexité O(1)) — bien plus rapide qu’une liste.
ens = {1, 2, 3, 4, 5}
print(3 in ens) # True
print(99 in ens) # FalseTrue
False
Si vous devez tester plusieurs fois l’appartenance d’éléments à une collection, convertissez-la en set d’abord :
# ❌ Lent sur une grande liste
grande_liste = list(range(1_000_000))
if 500_000 in grande_liste:
...
# ✅ Rapide
grand_set = set(grande_liste)
if 500_000 in grand_set:
...Cette optimisation est souvent testée au niveau Opérationnel et Avancé du TOSA.
C’est ce qui fait la valeur unique des sets : effectuer des opérations mathématiques d’ensembles.
| Opérateur | Méthode équivalente |
|---|---|
a \| b |
a.union(b) |
a = {1, 2, 3}
b = {3, 4, 5}
print(a | b)
print(a.union(b)){1, 2, 3, 4, 5}
{1, 2, 3, 4, 5}
| Opérateur | Méthode équivalente |
|---|---|
a & b |
a.intersection(b) |
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a & b)
print(a.intersection(b)){3, 4}
{3, 4}
a qui ne sont pas dans b| Opérateur | Méthode équivalente |
|---|---|
a - b |
a.difference(b) |
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a - b) # {1, 2} — dans a mais pas dans b
print(b - a) # {5, 6} — dans b mais pas dans a{1, 2}
{5, 6}
| Opérateur | Méthode équivalente |
|---|---|
a ^ b |
a.symmetric_difference(b) |
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a ^ b) # {1, 2, 5, 6} — sans les éléments communs{1, 2, 5, 6}
| Opération | Opérateur | Méthode | Résultat |
|---|---|---|---|
| Union | a \| b |
a.union(b) |
Tout |
| Intersection | a & b |
a.intersection(b) |
Ce qui est commun |
| Différence | a - b |
a.difference(b) |
Dans a uniquement |
| Diff. symétrique | a ^ b |
a.symmetric_difference(b) |
Pas en commun |
| Méthode | Effet |
|---|---|
a.issubset(b) ou a <= b |
a est-il inclus dans b ? |
a.issuperset(b) ou a >= b |
a contient-il b ? |
a.isdisjoint(b) |
a et b n’ont aucun élément commun ? |
a = {1, 2}
b = {1, 2, 3, 4}
c = {10, 20}
print(a.issubset(b)) # True
print(b.issuperset(a)) # True
print(a.isdisjoint(c)) # True
print(a.isdisjoint(b)) # False (ils partagent 1 et 2)True
True
True
False
L’usage #1 des sets dans du code Python réel.
# À partir d'une liste avec doublons
notes = [12, 15, 12, 9, 15, 17, 12, 9]
notes_uniques = set(notes)
print(notes_uniques)
# Si on veut RÉCUPÉRER une liste sans doublons
liste_sans_doublons = list(set(notes))
print(liste_sans_doublons){9, 12, 17, 15}
[9, 12, 17, 15]
set() ne préserve pas l’ordre
Contrairement aux dicts (depuis 3.7), les ensembles ne garantissent pas l’ordre d’insertion.
Si vous avez besoin de supprimer les doublons en préservant l’ordre, utilisez plutôt :
notes = [12, 15, 12, 9, 15, 17, 12, 9]
# Astuce : les dicts préservent l'ordre, les clés sont uniques
notes_uniques_ordonnees = list(dict.fromkeys(notes))
print(notes_uniques_ordonnees)[12, 15, 9, 17]
Cette astuce est souvent demandée en entretien !
Python propose un type frozenset : un set immuable, comme un tuple est une liste immuable. On l’utilise rarement au niveau Basique, mais il est bon de savoir qu’il existe.
f = frozenset([1, 2, 3])
print(f, type(f))frozenset({1, 2, 3}) <class 'frozenset'>
f.add(4) # ❌ impossible, immuable--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[18], line 1 ----> 1 f.add(4) # ❌ impossible, immuable AttributeError: 'frozenset' object has no attribute 'add'
À la différence d’un set classique, un frozenset peut servir de clé de dictionnaire ou d’élément dans un autre set.
Tableau essentiel pour le TOSA — à connaître par cœur :
| Caractéristique | list |
tuple |
dict |
set |
|---|---|---|---|---|
| Syntaxe | [1, 2] |
(1, 2) |
{"a": 1} |
{1, 2} |
| Ordonné | ✅ | ✅ | ✅ (3.7+) | ❌ |
| Modifiable | ✅ | ❌ | ✅ | ✅ |
| Indexable | ✅ | ✅ | ❌ (par clé) | ❌ |
| Doublons autorisés | ✅ | ✅ | ❌ (clés) | ❌ |
| Accès | l[i] |
t[i] |
d[k] |
x in s |
Test in complexité |
O(n) | O(n) | O(1) | O(1) |
| Principaux usages | Collection générique | Données immuables | Données structurées | Unicité, ensembles |
Que renvoie {1, 2, 2, 3, 3, 3} ?
{1, 2, 2, 3, 3, 3}{1, 2, 3}[1, 2, 3]b) {1, 2, 3} — les doublons sont automatiquement supprimés à la création d’un set.
print({1, 2, 2, 3, 3, 3}){1, 2, 3}
Que vaut type({}) ?
setdicttuplelistb) dict — piège classique ! {} crée un dictionnaire vide, pas un ensemble vide. Pour un set vide : set().
print(type({})) # dict
print(type(set())) # set
print(type({1, 2})) # set (si non vide, ça marche)<class 'dict'>
<class 'set'>
<class 'set'>
Que renvoie {1, 2, 3} | {3, 4, 5} ?
{3}{1, 2, 4, 5}{1, 2, 3, 4, 5}c) {1, 2, 3, 4, 5} — l’opérateur | fait l’union (tous les éléments, sans doublons).
print({1, 2, 3} | {3, 4, 5}){1, 2, 3, 4, 5}
Que renvoie {1, 2, 3} & {2, 3, 4} ?
{1, 2, 3, 4}{2, 3}{1, 4}{2, 3, 4}b) {2, 3} — l’opérateur & fait l’intersection (éléments communs).
print({1, 2, 3} & {2, 3, 4}){2, 3}
Que vaut len(set([1, 2, 2, 3, 3, 3])) ?
3650a) 3 — la conversion en set supprime les doublons : {1, 2, 3}, donc longueur 3.
print(len(set([1, 2, 2, 3, 3, 3])))3
Que s’affiche-t-il ?
s = {1, 2, 3}
s.discard(99)
print(s){1, 2, 3}KeyError{1, 2, 3, 99}Nonea) {1, 2, 3} — discard() ne lève pas d’erreur si l’élément est absent. Contrairement à remove() qui aurait levé KeyError.
s = {1, 2, 3}
s.discard(99)
print(s){1, 2, 3}
Quelle est la différence principale entre set et list ?
inb) Les sets n’acceptent pas les doublons et ne sont pas ordonnés — c’est leur caractéristique distinctive. Ils acceptent tous les types immuables (pas que des nombres), sont modifiables (pas immuables), et in y est plus rapide que sur une liste.
Soit la liste fruits = ["pomme", "banane", "pomme", "cerise", "banane", "kiwi"].
Créez une liste fruits_uniques contenant chaque fruit une seule fois.
fruits = ["pomme", "banane", "pomme", "cerise", "banane", "kiwi"]
# Créer fruits_uniques sans doublons
fruits_uniques = ...
print(fruits_uniques)fruits = ["pomme", "banane", "pomme", "cerise", "banane", "kiwi"]
fruits_uniques = list(set(fruits))
print(fruits_uniques)['banane', 'pomme', 'cerise', 'kiwi']
Attention : l’ordre est perdu !
Utilise dict.fromkeys() (vu plus haut) :
fruits = ["pomme", "banane", "pomme", "cerise", "banane", "kiwi"]
fruits_uniques = list(dict.fromkeys(fruits))
print(fruits_uniques) # ordre préservé['pomme', 'banane', 'cerise', 'kiwi']
Deux classes ont leur liste d’étudiants :
classe_A = {"Alice", "Bob", "Charlie", "Diana", "Eve"}
classe_B = {"Charlie", "Diana", "Frank", "Grace"}Écrivez un programme qui affiche :
classe_A = {"Alice", "Bob", "Charlie", "Diana", "Eve"}
classe_B = {"Charlie", "Diana", "Frank", "Grace"}
# Répondre aux 5 questions en utilisant des opérations ensemblistesclasse_A = {"Alice", "Bob", "Charlie", "Diana", "Eve"}
classe_B = {"Charlie", "Diana", "Frank", "Grace"}
# 1. Dans les deux : intersection
print("Dans les deux :", classe_A & classe_B)
# 2. Seulement dans A : différence A - B
print("Seulement A :", classe_A - classe_B)
# 3. Seulement dans B : différence B - A
print("Seulement B :", classe_B - classe_A)
# 4. Dans l'un OU l'autre mais pas les deux : différence symétrique
print("Exclusifs :", classe_A ^ classe_B)
# 5. Total distinct : union
print("Total distinct :", len(classe_A | classe_B))Dans les deux : {'Charlie', 'Diana'}
Seulement A : {'Alice', 'Bob', 'Eve'}
Seulement B : {'Grace', 'Frank'}
Exclusifs : {'Alice', 'Bob', 'Grace', 'Eve', 'Frank'}
Total distinct : 7
Écrivez une fonction lettres_uniques(mot) qui renvoie l’ensemble des lettres présentes dans un mot (sans doublons, en minuscules).
Exemple : lettres_uniques("Banana") → {"b", "a", "n"}.
def lettres_uniques(mot):
...
print(lettres_uniques("Banana"))
print(lettres_uniques("Mississippi"))
print(lettres_uniques("Python"))def lettres_uniques(mot):
return set(mot.lower())
print(lettres_uniques("Banana"))
print(lettres_uniques("Mississippi"))
print(lettres_uniques("Python")){'b', 'a', 'n'}
{'i', 's', 'p', 'm'}
{'y', 't', 'p', 'h', 'n', 'o'}
def nb_lettres_distinctes(mot):
return len(set(mot.lower()))
for mot in ["Python", "Mississippi", "abécédaire"]:
print(f"{mot}: {nb_lettres_distinctes(mot)} lettres distinctes")Python: 6 lettres distinctes
Mississippi: 4 lettres distinctes
abécédaire: 8 lettres distinctes
def memes_lettres(mot1, mot2):
"""Deux mots utilisent-ils exactement les mêmes lettres ?"""
return set(mot1.lower()) == set(mot2.lower())
print(memes_lettres("listen", "silent")) # True (anagramme)
print(memes_lettres("python", "chaton")) # FalseTrue
False
{} est un dict vide, pas un set vide. Utilisez set().add, remove (erreur si absent), discard (sans erreur).in en O(1) → bien plus rapide qu’une liste pour les gros volumes.| union, & intersection, - différence, ^ diff. symétrique.list(set(liste)) pour dédoublonner (ordre perdu).list(dict.fromkeys(liste)).← Chapitre précédent : Les dictionnaires • Chapitre suivant : Les boucles →