Les sets en Python
Comme les dictionnaires, les sets sont des collections d'éléments non-ordonnées.
Dans un set, chaque élément doit être unique et immuable , c’est-à- dire qu'il ne peut pas être modifié.
On peut donc stocker des chaînes de caractères, des nombres et des tuples dans un set mais pas de listes ou de dictionnaires !
En revanche, le set en lui-même peut être modifié ! On peut y ajouter des objets et aussi en supprimer.
Les sets sont souvent utilisés pour contrôler les doublons et effectuer des opérations sur les ensembles comme les unions, les différences, les intersections, etc.
Créer un set
Il existe deux façons de créer un set en Python.
La première consiste à utiliser la fonction set()
:
s = set(iterable)
Lorsque vous définissez un set avec cette fonction, vous devez passer un objet itérable comme une liste, un tuple ou une chaîne de caractères :
s = set() # Set vide
s = set(['spam', 'eggs', 'knights', 'ham']) # {'ham', 'knights', 'spam', 'eggs'}
s = set(('spam', 'eggs', 'knights', 'ham')) # {'ham', 'knights', 'spam', 'eggs'}
s = set('eggs') # {'e', 's', 'g'}
Je peux passer une liste en argument alors que c'est un objet muable.
Cependant, la fonction set()
retourne bien un set dans lequel la liste a été
décomposée en chaînes de caractères, qui elles, sont bien des objets immuables
🙂
L'autre manière de faire est d'utiliser les accolades {}
:
s = {item1, item2, item3}
s = {'spam', 'eggs', 'knights'} # {'spam', 'eggs', 'knights'}
Chaque objet passé entre les accolades devient un item distinct du set , que cet objet soit itérable ou non.
C'est ce qui différencie les deux méthodes de création d'un set !
Par exemple :
s = set('eggs') # {'e', 's', 'g'} => Itérable où chaque élément est évalué
s = {'eggs'} # {'eggs'} => Reste un élément distinct du set
Les accolades sont également utilisées pour créer des dictionnaires. Python comprend tout seul s'il s'agit d'un dictionnaire ou d'un set grâce aux éléments entre les accolades. Dans le cas d'un dictionnaire, on retrouve des paires de clés: valeurs alors que dans un set on retrouve uniquement des objets séparés par une virgule.
Modifier un set
Les sets étant désordonnés, on ne peut pas accéder aux éléments qu'ils contiennent grâce à un index :
s = {'spam', 'eggs', 'knights'}
print(s[0]) # TypeError: 'set' object is not subscriptable
Pour rappel, on ne peut pas modifier les éléments d'un set car ils sont immuables !
Du coup, Python met à notre disposition deux méthodes pour ajouter des éléments à l'intérieur d'un set !
Ajouter un élément avec add(objet)
:
s = {'spam', 'eggs', 'knights'}
s.add('ham')
print(s) # {'ham', 'knights', 'spam', 'eggs'}
Met à jour le set avec les éléments contenus dans l'itérable avec
update(iterable)
:
s = {'spam', 'eggs', 'knights'}
s.update(['ham', 'lumberjack', 'bones'])
print(s) # {'ham', 'bones', 'lumberjack', 'spam', 'eggs', 'knights'}
Retirer certains éléments d'un set
On peut retirer les éléments d'un set grâce aux méthodes discard
et
remove
.
La méthode discard
ne modifie pas le set si l'élément à supprimer n'est pas
présent dans le set à l'inverse de remove
qui lèvera une exception :
s = {'ham', 'bones', 'lumberjack', 'spam', 'eggs', 'knights'}
print(s) # {'ham', 'bones', 'lumberjack', 'spam', 'eggs', 'knights'}
s.discard('bones')
print(s) # {'ham', 'lumberjack', 'spam', 'eggs', 'knights'}
s.remove('eggs')
print(s) # {'ham', 'lumberjack', 'spam', 'knights'}
s.discard('anything')
print(s) # {'ham', 'lumberjack', 'spam', 'knights'}
s.remove('anything') # KeyError: 'anything'
Vous pouvez aussi vider complètement un set avec la méthode clear
:
s = {'ham', 'bones', 'lumberjack', 'spam', 'eggs', 'knights'}
s.clear() # set()
Même si le set a été créé en utilisant les accolades, la méthode clear
retourne set()
et non {}
(car des accolades vides correspondent à un
dictionnaire).
Les opérations possibles sur un set
Les sets peuvent être utilisés pour réaliser des opérations mathématiques comme des unions , des différences , des intersections ou encore des différences symétriques.
Union
Une union entre A
et B
crée un set avec tous les éléments de A
et de
B
.
Pour créer cette union, on utilise le symbole |
(on peut aussi utiliser la
méthode union
) :
A = {1, 2, 3, 4, 5}
B = {6, 7, 8, 9, 10}
print(A | B) # {1, 2, 3, 4, 5, 6, 7, 8, 9,10}
print(A.union(B)) # {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Intersection
Une intersection entre A
et B
crée un set avec tous les éléments communs
de A
et de B
.
Pour créer cette intersection, on utilise le symbole &
(on peut aussi
utiliser la méthode intersection
) :
A = {3, 4, 5, 6, 7}
B = {6, 7, 8, 9, 10}
print(A & B) # {6, 7}
print(A.intersection(B)) # {6, 7}
Différence
Une différence de A
sur B
crée un set avec tous les éléments uniquement
compris dans A
mais pas dans B
.
Pour créer cette différence, on utilise le symbole -
(on peut aussi utiliser
la méthode difference
) :
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
print(A - B) # {1, 2, 3}
print(A.difference(B)) # {1, 2, 3}
Différence symétrique
Une différence symétrique entre A
et B
crée un set avec tous les éléments
compris dans A
et dans B
mais pas dans les deux à la fois.
Pour créer cette différence, on utilise le symbole ^
(on peut aussi utiliser
la méthode symmetric_difference
) :
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
print(A ^ B) # {1, 2, 3, 6, 7, 8}
print(A.symmetric_difference(B)) # {1, 2, 3, 6, 7, 8}
Frozenset
Les frozenset ont exactement les mêmes caractéristiques qu'un set classique à la différence qu'ils ne peuvent plus être modifiés une fois créés.
On les définit en utilisant la fonction frozenset()
:
s = frozenset(['bones', 'lumberjack', 'spam', 'eggs', 'knights'])
print(s) # frozenset({'knights', 'spam', 'lumberjack', 'bones', 'eggs'})
print(len(s)) # 5
print(s.add('bones')) # AttributeError: 'frozenset' object has no attribute 'add'