Les objets de type “ensemble” (set dans le language Python) sont des structures de données qui modélisent la notion mathématique d’ensemble. Un ensemble (au sens Python) peut contenir des valeurs de type quelconque (mais ce type doit être “hashable” : dans la pratique, cela exclut les listes, les dictionnaires et les ensembles), et une même valeur ne peut apparaître qu’une seule fois. De plus les éléments d’un objet de type ensemble ne sont pas ordonnés (on ne peut pas y accéder par un indice : on peut juste savoir si une valeur est ou n’est pas élément de l’ensemble).
On forme un ensemble par la séquence de ses éléments (valeurs), encadrée par { et }, ou en utilisant le constructeur set (appliqué à un itérable quelconque).
|
1 2 3 4 5 6 |
>>> e = {1,5,2,3,2,7,5,2,1,3,2} # forme un ensemble par une séquence de valeurs entre { et } >>> e = set([1,5,2,3,2,7,5,2,1,3,2]) # même résultat en convertissant une liste >>> e # dans un ensemble, tous les doublons ont été éliminés {1, 2, 3, 5, 7} >>> set('abracadabra') # l'ensemble des caractères distincts d'une chaîne {'d', 'r', 'a', 'c', 'b'} |
Les objets de type “ensemble” sont mutables. Voici quelques méthodes applicables à un objet ens de type ensemble (set). On note elt une valeur susceptible d’appartenir ou d’être ajoutée à l’ensemble ens :
len(ens) |
renvoie le cardinal (le nombre d’éléments) de l’ensemble |
ens.add(elt) |
ajoute un élément à un ensemble |
ens.remove(elt)ens .discard(elt) |
retire un élément à un ensemble (KeyError si élément absent)retire un élément à un ensemble s’il y est effectivement (pas d’erreur sinon) |
elt in ens |
renvoie True si l’élément est présent dans l’ensemble, False sinon |
elt not in ens |
renvoie True si l’élément est absent de l’ensemble, False sinon |
ens.clear() |
efface le contenu de l’ensemble |
ens.copy() |
renvoie une copie de l’ensemble, indépendante de l’original |
ens.pop() |
renvoie et supprime un élement arbitraire de l’ensemble (KeyError si ensemble vide) |
On continue sur la lancée de l’exemple précédent (avec l’ensemble e = {1, 2, 3, 5, 7}) :
|
1 2 3 4 5 6 7 8 |
>>> e.discard(5) # on retire l'élément 5 (pas d'erreur s'il avait été absent) >>> e {1, 2, 3, 7} >>> e.add(0) # on ajoute l'élément 0 >>> e {0, 1, 2, 3, 7} >>> 4 in e # on demande si 4 est dans l'ensemble False |
Les objets de type “ensemble” ont des méthodes pour les opérations ensemblistes usuelles :
ens1.isdisjoint(ens2) |
renvoie True si ens1 et ens2 sont disjoints |
ens1 <= ens2 |
renvoie True si ens1 est inclus dans ens2 |
ens1 < ens2 |
renvoie True si ens1 est strictement inclus dans ens2 |
ens1 >= ens2 |
renvoie True si ens1 contient ens2 |
ens1 > ens2 |
renvoie True si ens1 contient strictement ens2 |
ens1 | ens2 |
réunion de ens1 et ens2 |
ens1 & ens2 |
intersection de ens1 et ens2 |
ens1 - ens2 |
différence de ens1 et ens2 |
ens1 ^ ens2 |
différence symétrique de ens1 et ens2 |
Voici quelques exemples (on voit que l’ordre des éléments d’un ensemble est imprévisible) :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
>>> m3 = set(range(0,50,3)); m3 # les multiples de 3 dans l'intervalle [0,50[ {0, 33, 3, 36, 6, 39, 9, 42, 12, 45, 15, 48, 18, 21, 24, 27, 30} >>> m5 = set(range(0,50,5)); m5 # les multiples de 5 dans l'intervalle [0,50[ {0, 35, 5, 40, 10, 45, 15, 20, 25, 30} >>> m7 = set(range(0,50,7)); m7 # les multiples de 7 dans l'intervalle [0,50[ {0, 35, 7, 42, 14, 49, 21, 28} >>> m5 | m7 # union des multiples de 5 ou de 7 {0, 35, 5, 7, 40, 10, 45, 14, 15, 49, 20, 21, 25, 28, 42, 30} >>> sorted(m5 | m7) # renvoie une liste (pas un ensemble!) triée [0, 5, 7, 10, 14, 15, 20, 21, 25, 28, 30, 35, 40, 42, 45, 49] >>> m3 - m7 # les multiples de 3 qui ne sont pas multiples de 7 {33, 3, 36, 6, 39, 9, 12, 45, 15, 48, 18, 24, 27, 30} >>> m7 - m3 # les multiples de 7 qui ne sont pas multiples de 3 {49, 35, 28, 14, 7} >>> m3 + m7 # attention, pas d'opération + sur les ensembles !!! <...> TypeError: unsupported operand type(s) for +: 'set' and 'set' >>> m3 ^ m5 # les multiples de 3 ou 5, mais pas de 15 {3, 5, 6, 9, 10, 12, 18, 20, 21, 24, 25, 27, 33, 35, 36, 39, 40, 42, 48} >>> m3 & m5 # les multiples de 3 et de 5 (c'est-à-dire ceux de 15) {0, 45, 30, 15} |
On dispose aussi d’opérations avec assignation permettant de modifier facilement un ensemble.
ens1 |= ens2 |
remplace ens1 par la réunion des deux ensembles |
ens1 &= ens2 |
remplace ens1 par leur intersection |
ens1 -= ens2 |
remplace ens1 par leur différence |
ens1 ^= ens2 |
remplace ens1 par leur différence symétrique |
En reprenant les ensembles m7 et m3 précédents, on illustre le caractère mutable des objets de type ensemble :
|
1 2 3 4 5 6 7 8 9 |
>>> m7bis = m7 # m7bis et m7 c'est pareil >>> m7ter = m7.copy() # m7ter est une copie indépendante de m7 >>> m7 -= m3 # retire de m7 les éléments de l'ensemble m3 >>> m7 # on obtient les multiples de 7 non multiples de 3 {35, 7, 14, 49, 28} >>> m7bis # la modification s'est répercutée sur m7bis {35, 7, 14, 49, 28} >>> m7ter # mais pas sur m7ter, qui garde son indépendance! {0, 35, 7, 42, 14, 49, 21, 28} |
Remarque : Python propose également le type frozenset, pour modéliser les ensembles non mutables. Les objets de type frozenset sont donc des ensembles “gelés”, dont on ne peut pas modifier le contenu ni la longueur (à moins de redéfinir l’objet complètement). Ils disposent des méthodes des objets de type set (sauf ceux qui ont trait à la mutabilité, bien sûr). On pourra se reporter à http://docs.python.org/3.3/library/stdtypes.html#frozenset