109 votes

Python supprimer un ensemble d'un ensemble

Selon mon interprétation de la documentation de Python 2.7.2 pour Built-In Types 5.7 Set Types, il devrait être possible de supprimer les éléments de l'ensemble A de l'ensemble B en passant A à set.remove(elem) ou set.discard(elem)

À partir de la documentation pour 2.7.2:

Remarque, l'argument elem pour les méthodes __contains__(), remove() et discard() peut être un ensemble.

Je comprends que je peux passer un set à remove(elem) ou discard(elem) et que tous ces éléments seront supprimés de l'ensemble cible. Je l'utiliserais pour faire quelque chose d'étrange comme supprimer toutes les voyelles d'une chaîne ou supprimer tous les mots communs d'un histogramme de fréquence de mots. Voici le code de test:

Python 2.7.2 (par défaut, 12 juin 2011, 14:24:46) [M...
Tapez "aide", "copyright", "crédits" ou "licence"
>>> a = set(range(10))
>>> b = set(range(5,10))
>>> a
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b
set([8, 9, 5, 6, 7])
>>> a.remove(b)
Traceback (most recent call last):
  File "", line 1, in 
KeyError: set([8, 9, 5, 6, 7])
>>> a.discard(b)
>>> a
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>>

Que je m'attends à retourner:

>>> a
set([0, 1, 2, 3, 4])

Je sais que je peux accomplir cela avec a.difference(b) qui renvoie un nouvel ensemble; ou avec set.difference_update(other); ou avec les opérateurs d'ensemble a -= b, qui modifient l'ensemble en place.

Est-ce un bug dans la documentation? set.remove(elem) peut-il en fait ne pas prendre un ensemble comme argument? Ou la documentation fait-elle référence à des ensembles d'ensembles? Étant donné que difference_update accomplit mon interprétation, je suppose que c'est le second cas.

Est-ce assez clair?

ÉDIT Après 3 ans de travail supplémentaire (professionnel) en Python, et étant récemment revenu sur cette question, je réalise maintenant que ce que j'essayais réellement de faire pourrait être accompli avec:

>>> c = a.difference(b)
set([0,1,2,3,4])

ce que j'essayais initialement de faire.

ÉDIT Après 4 ans de plus de développement en Python... je réalise que cette opération peut être exprimée de manière plus propre en utilisant des littéraux d'ensemble et l'opérateur -; et qu'il est plus complet de montrer que la différence d'ensemble n'est pas commutative.

>>> a={0,1,2,3}
>>> b={2,3,4,5}
>>> a-b
set([0, 1])
>>> b-a
set([4, 5])

76voto

Nic Scozzaro Points 742

set1-ensemble2

ensemble1 = {0,1,2,3}
ensemble2 = {2,3,4,5}

ensemble1 - ensemble2  # {0, 1}
ensemble2 - ensemble1  # {4, 5}

Cependant, notez que pour une raison quelconque vous ne pouvez pas "+" des ensembles en python...

29voto

nitsas Points 720

Vous avez déjà répondu à la question. Il s'agit d'ensembles de ensembles (en fait des ensembles contenant des frozensets).

Le paragraphe auquel vous faites référence commence par :

Notez que l'argument elem pour les méthodes __contains__(), remove() et discard() peut être un ensemble.

ce qui signifie que b dans a.remove(b) peut être un ensemble, et continue avec :

Pour supporter la recherche d'un frozenset équivalent, l'ensemble elem est temporairement muté pendant la recherche et ensuite restauré. Pendant la recherche, l'ensemble elem ne doit pas être lu ou modifié car il n'a pas de valeur significative.

ce qui signifie que si b est un ensemble, a.remove(b) va parcourir a pour trouver un frozenset équivalent à b et le supprimer (ou générer une KeyError s'il n'existe pas).

10voto

Ling Points 135

Vous ne pouvez pas avoir des ensembles de ensembles en Python car un ensemble est mutable. Au lieu de cela, vous pouvez avoir des ensembles de frozensets. D'autre part, vous pouvez appeler __contains__(), remove(), et discard() avec un ensemble. Voici un exemple:

a = set([frozenset([2])])
set([2]) in a       # vous obtenez True
a.remove(set([2]))  # a est maintenant vide

Donc, la réponse à votre question est que la documentation fait référence à des ensembles de frozensets.

2voto

Josh Smeaton Points 18165

Je consulte l'aide intégrée pour différentes versions de Python (pour Mac). Voici les résultats.

  • python2.5

remove(...)
Retire un élément d'un ensemble; il doit en être membre.
Si l'élément n'est pas un membre, une KeyError est émise.

  • python2.6

remove(...)
Retire un élément d'un ensemble; il doit en être membre. Si l'élément n'est pas un membre, une KeyError est émise.

  • python2.7

remove(...)
Retire un élément d'un ensemble; il doit en être membre. Si l'élément n'est pas un membre, une KeyError est émise.

La documentation à laquelle vous faites référence, en entier, dit en réalité:

Remarquez, l'argument elem des méthodes __contains__(), remove() et discard() peut être un ensemble. Pour prendre en charge la recherche d'un frozenset équivalent, l'ensemble elem est temporairement modifié pendant la recherche puis restauré.

Cela semble être une note de bas de page, qui suggère que l'argument peut être un ensemble, mais sauf s'il trouve un frozenset correspondant dans l'ensemble, il ne sera pas retiré. La mention de la modification de l'ensemble est pour qu'il puisse être hashé afin de rechercher un frozenset correspondant.

1voto

Amber Points 159296

Je pense que la documentation fait référence à des ensembles de (ensembles) gelés, oui.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X