Ensembles en Python

Ensembles en Python

Vous vous souvenez peut-être avoir appris sur lessets et lesset theory à un moment donné de votre formation mathématique. Peut-être vous souvenez-vous même des diagrammes de Venn:

Venn diagram

Si cela ne vous dit rien, ne vous inquiétez pas! Ce didacticiel devrait toujours être facilement accessible pour vous.

En mathématiques, une définition rigoureuse d'un ensemble peut être abstraite et difficile à saisir. En pratique, cependant, un ensemble peut être considéré simplement comme une collection bien définie d'objets distincts, généralement appeléselements oumembers.

Le regroupement d'objets dans un ensemble peut également être utile dans la programmation, et Python fournit un type d'ensemble intégré pour le faire. Les ensembles se distinguent des autres types d'objets par les opérations uniques qui peuvent y être effectuées.

Here’s what you’ll learn in this tutorial: Vous verrez comment définir les objetsset en Python et découvrirez les opérations qu'ils prennent en charge. Comme avec les didacticiels précédents sur les listes et les dictionnaires, lorsque vous avez terminé ce didacticiel, vous devez avoir une bonne idée du moment où un ensemble est un choix approprié. Vous en apprendrez également sur lesfrozen sets, qui sont similaires aux ensembles, à l'exception d'un détail important.

__ Take the Quiz: Testez vos connaissances avec notre quiz interactif «Ensembles Python». À la fin, vous recevrez un score afin que vous puissiez suivre vos progrès d'apprentissage au fil du temps:

Définition d'un ensemble

Le typeset intégré de Python présente les caractéristiques suivantes:

  • Les ensembles ne sont pas classés.

  • Les éléments d'ensemble sont uniques. Les éléments en double ne sont pas autorisés.

  • Un ensemble lui-même peut être modifié, mais les éléments contenus dans l'ensemble doivent être d'un type immuable.

Voyons ce que cela signifie et comment vous pouvez travailler avec des ensembles en Python.

Un ensemble peut être créé de deux manières. Tout d'abord, vous pouvez définir un ensemble avec la fonctionset() intégrée:

x = set()

Dans ce cas, l'argument<iter> est un itérable - encore une fois, pour le moment, pensez liste ou tuple - qui génère la liste des objets à inclure dans l'ensemble. Ceci est analogue à l'argument<iter> donné à la méthode de liste.extend():

>>>

>>> x = set(['foo', 'bar', 'baz', 'foo', 'qux'])
>>> x
{'qux', 'foo', 'bar', 'baz'}

>>> x = set(('foo', 'bar', 'baz', 'foo', 'qux'))
>>> x
{'qux', 'foo', 'bar', 'baz'}

Les chaînes sont également itérables, donc une chaîne peut également être transmise àset(). Vous avez déjà vu quelist(s) génère une liste des caractères de la chaînes. De même,set(s) génère un ensemble de caractères danss:

>>>

>>> s = 'quux'

>>> list(s)
['q', 'u', 'u', 'x']
>>> set(s)
{'x', 'u', 'q'}

Vous pouvez voir que les ensembles résultants ne sont pas ordonnés: l'ordre d'origine, tel que spécifié dans la définition, n'est pas nécessairement conservé. De plus, les valeurs en double ne sont représentées qu'une seule fois dans l'ensemble, comme avec la chaîne'foo' dans les deux premiers exemples et la lettre'u' dans le troisième.

Alternativement, un ensemble peut être défini avec des accolades ({}):

x = {, , ..., }

Lorsqu'un ensemble est défini de cette manière, chaque<obj> devient un élément distinct de l'ensemble, même s'il s'agit d'un itérable. Ce comportement est similaire à celui de la méthode de liste.append().

Ainsi, les ensembles présentés ci-dessus peuvent également être définis comme ceci:

>>>

>>> x = {'foo', 'bar', 'baz', 'foo', 'qux'}
>>> x
{'qux', 'foo', 'bar', 'baz'}

>>> x = {'q', 'u', 'u', 'x'}
>>> x
{'x', 'q', 'u'}

Récapituler:

  • L'argument deset() est un itérable. Il génère une liste d'éléments à placer dans l'ensemble.

  • Les objets entre accolades sont placés intacts dans l'ensemble, même s'ils sont itérables.

Observez la différence entre ces deux définitions d'ensemble:

>>>

>>> {'foo'}
{'foo'}

>>> set('foo')
{'o', 'f'}

Un ensemble peut être vide. Cependant, rappelez-vous que Python interprète les accolades vides ({}) comme un dictionnaire vide, donc la seule façon de définir un ensemble vide est d'utiliser la fonctionset():

>>>

>>> x = set()
>>> type(x)

>>> x
set()

>>> x = {}
>>> type(x)

Un ensemble vide est faux dans un contexte booléen:

>>>

>>> x = set()
>>> bool(x)
False
>>> x or 1
1
>>> x and 1
set()

Vous pourriez penser que les ensembles les plus intuitifs contiendraient des objets similaires, par exemple, des nombres pairs ou des noms de famille:

>>>

>>> s1 = {2, 4, 6, 8, 10}
>>> s2 = {'Smith', 'McArthur', 'Wilson', 'Johansson'}

Cependant, Python n'en a pas besoin. Les éléments d'un ensemble peuvent être des objets de différents types:

>>>

>>> x = {42, 'foo', 3.14159, None}
>>> x
{None, 'foo', 42, 3.14159}

N'oubliez pas que les éléments définis doivent être immuables. Par exemple, un tuple peut être inclus dans un ensemble:

>>>

>>> x = {42, 'foo', (1, 2, 3), 3.14159}
>>> x
{42, 'foo', 3.14159, (1, 2, 3)}

Mais les listes et les dictionnaires sont mutables, ils ne peuvent donc pas être des éléments définis:

>>>

>>> a = [1, 2, 3]
>>> {a}
Traceback (most recent call last):
  File "", line 1, in 
    {a}
TypeError: unhashable type: 'list'

>>> d = {'a': 1, 'b': 2}
>>> {d}
Traceback (most recent call last):
  File "", line 1, in 
    {d}
TypeError: unhashable type: 'dict'

Définir la taille et l'adhésion

La fonctionlen() renvoie le nombre d'éléments dans un ensemble, et les opérateursin etnot in peuvent être utilisés pour tester l'appartenance:

>>>

>>> x = {'foo', 'bar', 'baz'}

>>> len(x)
3

>>> 'bar' in x
True
>>> 'qux' in x
False

Fonctionnant sur un ensemble

De nombreuses opérations qui peuvent être utilisées pour les autres types de données composites de Python n'ont pas de sens pour les ensembles. Par exemple, les ensembles ne peuvent pas être indexés ou tranchés. Cependant, Python fournit toute une série d'opérations sur les objets d'ensemble qui imitent généralement lesoperations définis pour les ensembles mathématiques.

Opérateurs vs Les méthodes

La plupart, mais pas tout à fait, des opérations de définition en Python peuvent être effectuées de deux manières différentes: par opérateur ou par méthode. Voyons comment fonctionnent ces opérateurs et ces méthodes, en utilisant set union comme exemple.

Étant donné deux ensembles,x1 etx2, l'union dex1 etx2 est un ensemble composé de tous les éléments de l'un ou l'autre ensemble.

Considérez ces deux ensembles:

x1 = {'foo', 'bar', 'baz'}
x2 = {'baz', 'qux', 'quux'}

L'union dex1 etx2 est{'foo', 'bar', 'baz', 'qux', 'quux'}.

Note: Notez que l'élément'baz', qui apparaît à la fois dansx1 etx2, n'apparaît qu'une seule fois dans l'union. Les ensembles ne contiennent jamais de valeurs en double.

En Python, set union peut être effectué avec l'opérateur|:

>>>

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'baz', 'qux', 'quux'}
>>> x1 | x2
{'baz', 'quux', 'qux', 'bar', 'foo'}

L'union définie peut également être obtenue avec la méthode.union(). La méthode est invoquée sur l'un des ensembles et l'autre est passée en argument:

>>>

>>> x1.union(x2)
{'baz', 'quux', 'qux', 'bar', 'foo'}

De la manière dont ils sont utilisés dans les exemples ci-dessus, l'opérateur et la méthode se comportent de manière identique. Mais il y a une différence subtile entre eux. Lorsque vous utilisez l'opérateur|, les deux opérandes doivent être définis. La méthode.union(), par contre, prendra n'importe quel itérable comme argument, le convertira en un ensemble, puis effectuera l'union.

Observez la différence entre ces deux déclarations:

>>>

>>> x1 | ('baz', 'qux', 'quux')
Traceback (most recent call last):
  File "", line 1, in 
    x1 | ('baz', 'qux', 'quux')
TypeError: unsupported operand type(s) for |: 'set' and 'tuple'

>>> x1.union(('baz', 'qux', 'quux'))
{'baz', 'quux', 'qux', 'bar', 'foo'}

Les deux tentent de calculer l'union dex1 et du tuple('baz', 'qux', 'quux'). Cela échoue avec l'opérateur| mais réussit avec la méthode.union().

Opérateurs et méthodes disponibles

Vous trouverez ci-dessous une liste des opérations d'ensemble disponibles en Python. Certains sont exécutés par l'opérateur, certains par la méthode et d'autres par les deux. Le principe décrit ci-dessus s'applique généralement: lorsqu'un ensemble est attendu, les méthodes acceptent généralement tout itérable comme argument, mais les opérateurs nécessitent des ensembles réels comme opérandes.

x1.union(x2[, x3 ...])

x1 | x2 [| x3 ...]

Calculez l'union de deux ensembles ou plus.

x1.union(x2) etx1 | x2 renvoient tous les deux l'ensemble de tous les éléments dansx1 oux2:

>>>

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'baz', 'qux', 'quux'}

>>> x1.union(x2)
{'foo', 'qux', 'quux', 'baz', 'bar'}

>>> x1 | x2
{'foo', 'qux', 'quux', 'baz', 'bar'}

Plus de deux ensembles peuvent être spécifiés avec l'opérateur ou la méthode:

>>>

>>> a = {1, 2, 3, 4}
>>> b = {2, 3, 4, 5}
>>> c = {3, 4, 5, 6}
>>> d = {4, 5, 6, 7}

>>> a.union(b, c, d)
{1, 2, 3, 4, 5, 6, 7}

>>> a | b | c | d
{1, 2, 3, 4, 5, 6, 7}

L'ensemble résultant contient tous les éléments présents dans l'un des ensembles spécifiés.

x1.intersection(x2[, x3 ...])

x1 & x2 [& x3 ...]

Calculez l'intersection de deux ensembles ou plus.

x1.intersection(x2) etx1 & x2 renvoient l'ensemble des éléments communs auxx1 etx2:

>>>

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'baz', 'qux', 'quux'}

>>> x1.intersection(x2)
{'baz'}

>>> x1 & x2
{'baz'}

Vous pouvez spécifier plusieurs ensembles avec la méthode et l'opérateur d'intersection, tout comme vous pouvez le faire avec l'union d'ensemble:

>>>

>>> a = {1, 2, 3, 4}
>>> b = {2, 3, 4, 5}
>>> c = {3, 4, 5, 6}
>>> d = {4, 5, 6, 7}

>>> a.intersection(b, c, d)
{4}

>>> a & b & c & d
{4}

L'ensemble résultant ne contient que des éléments qui sont présents dans tous les ensembles spécifiés.

x1.difference(x2[, x3 ...])

x1 - x2 [- x3 ...]

Calculez la différence entre deux ou plusieurs ensembles.

x1.difference(x2) etx1 - x2 renvoient l'ensemble de tous les éléments qui sont enx1 mais pas enx2:

>>>

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'baz', 'qux', 'quux'}

>>> x1.difference(x2)
{'foo', 'bar'}

>>> x1 - x2
{'foo', 'bar'}

Une autre façon de penser à cela est quex1.difference(x2) etx1 - x2 renvoient l'ensemble qui résulte lorsque des éléments dex2 sont supprimés ou soustraits dex1.

Encore une fois, vous pouvez spécifier plus de deux ensembles:

>>>

>>> a = {1, 2, 3, 30, 300}
>>> b = {10, 20, 30, 40}
>>> c = {100, 200, 300, 400}

>>> a.difference(b, c)
{1, 2, 3}

>>> a - b - c
{1, 2, 3}

Lorsque plusieurs ensembles sont spécifiés, l'opération est effectuée de gauche à droite. Dans l'exemple ci-dessus,a - b est calculé en premier, ce qui donne{1, 2, 3, 300}. Ensuite,c est soustrait de cet ensemble, laissant{1, 2, 3}:

set difference

x1.symmetric_difference(x2)

x1 ^ x2 [^ x3 ...]

Calculez lessymmetric difference entre les ensembles.

x1.symmetric_difference(x2) etx1 ^ x2 renvoient l'ensemble de tous les éléments dansx1 oux2, mais pas les deux:

>>>

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'baz', 'qux', 'quux'}

>>> x1.symmetric_difference(x2)
{'foo', 'qux', 'quux', 'bar'}

>>> x1 ^ x2
{'foo', 'qux', 'quux', 'bar'}

L'opérateur^ autorise également plus de deux ensembles:

>>>

>>> a = {1, 2, 3, 4, 5}
>>> b = {10, 2, 3, 4, 50}
>>> c = {1, 50, 100}

>>> a ^ b ^ c
{100, 5, 10}

Comme pour l'opérateur de différence, lorsque plusieurs ensembles sont spécifiés, l'opération est effectuée de gauche à droite.

Curieusement, bien que l'opérateur^ autorise plusieurs ensembles, la méthode.symmetric_difference() ne permet pas:

>>>

>>> a = {1, 2, 3, 4, 5}
>>> b = {10, 2, 3, 4, 50}
>>> c = {1, 50, 100}

>>> a.symmetric_difference(b, c)
Traceback (most recent call last):
  File "", line 1, in 
    a.symmetric_difference(b, c)
TypeError: symmetric_difference() takes exactly one argument (2 given)

x1.isdisjoint(x2)

Détermine si deux ensembles ont ou non des éléments en commun.

x1.isdisjoint(x2) renvoieTrue six1 etx2 n'ont aucun élément en commun:

>>>

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'baz', 'qux', 'quux'}

>>> x1.isdisjoint(x2)
False

>>> x2 - {'baz'}
{'quux', 'qux'}
>>> x1.isdisjoint(x2 - {'baz'})
True

Six1.isdisjoint(x2) estTrue, alorsx1 & x2 est l'ensemble vide:

>>>

>>> x1 = {1, 3, 5}
>>> x2 = {2, 4, 6}

>>> x1.isdisjoint(x2)
True
>>> x1 & x2
set()

Note: Aucun opérateur ne correspond à la méthode.isdisjoint().

x1.issubset(x2)

x1 <= x2

Déterminez si un ensemble est un sous-ensemble de l'autre.

En théorie des ensembles, un ensemblex1 est considéré comme un sous-ensemble d'un autre ensemblex2 si chaque élément dex1 est enx2.

x1.issubset(x2) etx1 <= x2 renvoientTrue six1 est un sous-ensemble dex2:

>>>

>>> x1 = {'foo', 'bar', 'baz'}
>>> x1.issubset({'foo', 'bar', 'baz', 'qux', 'quux'})
True

>>> x2 = {'baz', 'qux', 'quux'}
>>> x1 <= x2
False

Un ensemble est considéré comme un sous-ensemble de lui-même:

>>>

>>> x = {1, 2, 3, 4, 5}
>>> x.issubset(x)
True
>>> x <= x
True

Cela semble peut-être étrange. Mais cela correspond à la définition - chaque élément dex est enx.

x1 < x2

Détermine si un ensemble est un sous-ensemble approprié de l'autre.

Un sous-ensemble approprié est identique à un sous-ensemble, sauf que les ensembles ne peuvent pas être identiques. Un ensemblex1 est considéré comme un sous-ensemble propre d'un autre ensemblex2 si chaque élément dex1 est enx2, etx1 etx2 sont inégal.

x1 < x2 renvoieTrue six1 est un sous-ensemble propre dex2:

>>>

>>> x1 = {'foo', 'bar'}
>>> x2 = {'foo', 'bar', 'baz'}
>>> x1 < x2
True

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'foo', 'bar', 'baz'}
>>> x1 < x2
False

Alors qu'un ensemble est considéré comme un sous-ensemble de lui-même, ce n'est pas un sous-ensemble propre de lui-même:

>>>

>>> x = {1, 2, 3, 4, 5}
>>> x <= x
True
>>> x < x
False

Note: L'opérateur< est le seul moyen de tester si un ensemble est un sous-ensemble approprié. Il n'y a pas de méthode correspondante.

x1.issuperset(x2)

x1 >= x2

Déterminez si un ensemble est un sur-ensemble de l'autre.

Un sur-ensemble est l'inverse d'un sous-ensemble. Un ensemblex1 est considéré comme un sur-ensemble d'un autre ensemblex2 six1 contient tous les éléments dex2.

x1.issuperset(x2) etx1 >= x2 renvoientTrue six1 est un sur-ensemble dex2:

>>>

>>> x1 = {'foo', 'bar', 'baz'}

>>> x1.issuperset({'foo', 'bar'})
True

>>> x2 = {'baz', 'qux', 'quux'}
>>> x1 >= x2
False

Vous avez déjà vu qu'un ensemble est considéré comme un sous-ensemble de lui-même. Un ensemble est également considéré comme un surensemble de lui-même:

>>>

>>> x = {1, 2, 3, 4, 5}
>>> x.issuperset(x)
True
>>> x >= x
True

x1 > x2

Détermine si un ensemble est un sur-ensemble approprié de l'autre.

Un surensemble correct est identique à un surensemble, sauf que les ensembles ne peuvent pas être identiques. Un ensemblex1 est considéré comme un sur-ensemble propre d'un autre ensemblex2 six1 contient tous les éléments dex2, etx1 etx2 ne le sont pas égal.

x1 > x2 renvoieTrue six1 est un sur-ensemble approprié dex2:

>>>

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'foo', 'bar'}
>>> x1 > x2
True

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'foo', 'bar', 'baz'}
>>> x1 > x2
False

Un ensemble n'est pas un véritable surensemble de lui-même:

>>>

>>> x = {1, 2, 3, 4, 5}
>>> x > x
False

Note: L'opérateur> est le seul moyen de tester si un ensemble est un sur-ensemble approprié. Il n'y a pas de méthode correspondante.

Modification d'un ensemble

Bien que les éléments contenus dans un ensemble doivent être de type immuable, les ensembles eux-mêmes peuvent être modifiés. Comme les opérations ci-dessus, il existe un mélange d'opérateurs et de méthodes qui peuvent être utilisés pour modifier le contenu d'un ensemble.

Opérateurs et méthodes d'affectation augmentée

Chacun des opérateurs d'union, d'intersection, de différence et de différence symétrique répertoriés ci-dessus a un formulaire d'affectation augmenté qui peut être utilisé pour modifier un ensemble. Pour chacun, il existe également une méthode correspondante.

x1.update(x2[, x3 ...])

x1 |= x2 [| x3 ...]

Modifiez un ensemble par union.

x1.update(x2) etx1 |= x2 ajoutent àx1 tous les éléments dex2 quex1 n'a pas déjà:

>>>

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'foo', 'baz', 'qux'}

>>> x1 |= x2
>>> x1
{'qux', 'foo', 'bar', 'baz'}

>>> x1.update(['corge', 'garply'])
>>> x1
{'qux', 'corge', 'garply', 'foo', 'bar', 'baz'}

x1.intersection_update(x2[, x3 ...])

x1 &= x2 [& x3 ...]

Modifiez un ensemble par intersection.

x1.intersection_update(x2) etx1 &= x2 mettent à jourx1, ne conservant que les éléments trouvés à la fois dansx1 etx2:

>>>

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'foo', 'baz', 'qux'}

>>> x1 &= x2
>>> x1
{'foo', 'baz'}

>>> x1.intersection_update(['baz', 'qux'])
>>> x1
{'baz'}

x1.difference_update(x2[, x3 ...])

x1 -= x2 [| x3 ...]

Modifiez un ensemble par différence.

x1.difference_update(x2) etx1 -= x2 mettent à jourx1, en supprimant les éléments trouvés dansx2:

>>>

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'foo', 'baz', 'qux'}

>>> x1 -= x2
>>> x1
{'bar'}

>>> x1.difference_update(['foo', 'bar', 'qux'])
>>> x1
set()

x1.symmetric_difference_update(x2)

x1 ^= x2

Modifiez un ensemble par différence symétrique.

x1.symmetric_difference_update(x2) etx1 ^= x2 mettent à jourx1, en conservant les éléments trouvés dansx1 oux2, mais pas les deux:

>>>

>>> x1 = {'foo', 'bar', 'baz'}
>>> x2 = {'foo', 'baz', 'qux'}
>>>
>>> x1 ^= x2
>>> x1
{'bar', 'qux'}
>>>
>>> x1.symmetric_difference_update(['qux', 'corge'])
>>> x1
{'bar', 'corge'}

Autres méthodes de modification des ensembles

Mis à part les opérateurs augmentés ci-dessus, Python prend en charge plusieurs méthodes supplémentaires qui modifient les ensembles.

x.add()

Ajoute un élément à un ensemble.

x.add(<elem>) ajoute<elem>, qui doit être un seul objet immuable, àx:

>>>

>>> x = {'foo', 'bar', 'baz'}

>>> x.add('qux')
>>> x
{'bar', 'baz', 'foo', 'qux'}

x.remove()

Supprime un élément d'un ensemble.

x.remove(<elem>) supprime<elem> dex. Python lève une exception si<elem> n'est pas dansx:

>>>

>>> x = {'foo', 'bar', 'baz'}

>>> x.remove('baz')
>>> x
{'bar', 'foo'}

>>> x.remove('qux')
Traceback (most recent call last):
  File "", line 1, in 
    x.remove('qux')
KeyError: 'qux'

x.discard()

Supprime un élément d'un ensemble.

x.discard(<elem>) supprime également<elem> dex. Cependant, si<elem> n'est pas dansx, cette méthode ne fait rien au lieu de lever une exception:

>>>

>>> x = {'foo', 'bar', 'baz'}

>>> x.discard('baz')
>>> x
{'bar', 'foo'}

>>> x.discard('qux')
>>> x
{'bar', 'foo'}

x.pop()

Supprime un élément aléatoire d'un ensemble.

x.pop() supprime et renvoie un élément choisi arbitrairement dansx. Six est vide,x.pop() lève une exception:

>>>

>>> x = {'foo', 'bar', 'baz'}

>>> x.pop()
'bar'
>>> x
{'baz', 'foo'}

>>> x.pop()
'baz'
>>> x
{'foo'}

>>> x.pop()
'foo'
>>> x
set()

>>> x.pop()
Traceback (most recent call last):
  File "", line 1, in 
    x.pop()
KeyError: 'pop from an empty set'

x.clear()

Efface un ensemble.

x.clear() supprime tous les éléments dex:

>>>

>>> x = {'foo', 'bar', 'baz'}
>>> x
{'foo', 'bar', 'baz'}
>>>
>>> x.clear()
>>> x
set()

Ensembles congelés

Python fournit un autre type intégré appeléfrozenset, qui est à tous égards exactement comme un ensemble, sauf qu'un frozenset est immuable. Vous pouvez effectuer des opérations sans modification sur un ensemble de frozensets:

>>>

>>> x = frozenset(['foo', 'bar', 'baz'])
>>> x
frozenset({'foo', 'baz', 'bar'})

>>> len(x)
3

>>> x & {'baz', 'qux', 'quux'}
frozenset({'baz'})

Mais les méthodes qui tentent de modifier un frozenset échouent:

>>>

>>> x = frozenset(['foo', 'bar', 'baz'])

>>> x.add('qux')
Traceback (most recent call last):
  File "", line 1, in 
    x.add('qux')
AttributeError: 'frozenset' object has no attribute 'add'

>>> x.pop()
Traceback (most recent call last):
  File "", line 1, in 
    x.pop()
AttributeError: 'frozenset' object has no attribute 'pop'

>>> x.clear()
Traceback (most recent call last):
  File "", line 1, in 
    x.clear()
AttributeError: 'frozenset' object has no attribute 'clear'

>>> x
frozenset({'foo', 'bar', 'baz'})

Deep Dive: Frozensets et affectation augmentée

Comme un ensemble de frozens est immuable, vous pourriez penser qu'il ne peut pas être la cible d'un opérateur d'affectation augmenté. Mais observez:

>>>

>>> f = frozenset(['foo', 'bar', 'baz'])
>>> s = {'baz', 'qux', 'quux'}

>>> f &= s
>>> f
frozenset({'baz'})

Ce qui donne?

Python n'effectue pas d'affectations augmentées sur les frozensets en place. L'instructionx &= s équivaut en fait àx = x & s. Il ne modifie pas lesx originaux. Il réaffectex à un nouvel objet et l'objetx référencé à l'origine a disparu.

Vous pouvez le vérifier avec la fonctionid():

>>>

>>> f = frozenset(['foo', 'bar', 'baz'])
>>> id(f)
56992872
>>> s = {'baz', 'qux', 'quux'}

>>> f &= s
>>> f
frozenset({'baz'})
>>> id(f)
56992152

f a un identifiant entier différent après l'affectation augmentée. Il a été réaffecté, pas modifié en place.

Certains objets en Python sont modifiés sur place lorsqu'ils sont la cible d'un opérateur d'affectation augmenté. Mais les frozensets ne le sont pas.

Les Frozensets sont utiles dans les situations où vous souhaitez utiliser un ensemble, mais vous avez besoin d'un objet immuable. Par exemple, vous ne pouvez pas définir un ensemble dont les éléments sont également des ensembles, car les éléments de l'ensemble doivent être immuables:

>>>

>>> x1 = set(['foo'])
>>> x2 = set(['bar'])
>>> x3 = set(['baz'])
>>> x = {x1, x2, x3}
Traceback (most recent call last):
  File "", line 1, in 
    x = {x1, x2, x3}
TypeError: unhashable type: 'set'

Si vous vous sentez vraiment obligé de définir un ensemble d'ensembles (hé, cela pourrait arriver), vous pouvez le faire si les éléments sont des ensembles de frozens, car ils sont immuables:

>>>

>>> x1 = frozenset(['foo'])
>>> x2 = frozenset(['bar'])
>>> x3 = frozenset(['baz'])
>>> x = {x1, x2, x3}
>>> x
{frozenset({'bar'}), frozenset({'baz'}), frozenset({'foo'})}

De même, rappelez-vous du tutoriel précédent surdictionaries qu'une clé de dictionnaire doit être immuable. Vous ne pouvez pas utiliser le type de jeu intégré comme clé de dictionnaire:

>>>

>>> x = {1, 2, 3}
>>> y = {'a', 'b', 'c'}
>>>
>>> d = {x: 'foo', y: 'bar'}
Traceback (most recent call last):
  File "", line 1, in 
    d = {x: 'foo', y: 'bar'}
TypeError: unhashable type: 'set'

Si vous devez utiliser des ensembles comme clés de dictionnaire, vous pouvez utiliser des frozensets:

>>>

>>> x = frozenset({1, 2, 3})
>>> y = frozenset({'a', 'b', 'c'})
>>>
>>> d = {x: 'foo', y: 'bar'}
>>> d
{frozenset({1, 2, 3}): 'foo', frozenset({'c', 'a', 'b'}): 'bar'}

Conclusion

Dans ce didacticiel, vous avez appris à définir les objetsset en Python et vous vous êtes familiarisé avec les fonctions, les opérateurs et les méthodes qui peuvent être utilisés pour travailler avec des ensembles.

Vous devriez maintenant être à l'aise avec les types de données intégrés de base fournis par Python.

Ensuite, vous commencerez à explorer comment le code qui opère sur ces objets est organisé et structuré dans un programme Python.

__ Take the Quiz: Testez vos connaissances avec notre quiz interactif «Ensembles Python». À la fin, vous recevrez un score afin que vous puissiez suivre vos progrès d'apprentissage au fil du temps: