Union de 2 ensembles ne contient pas tous les articles

Comment se fait-il que lorsque je change l’ordre des deux ensembles dans les unions ci-dessous, j’obtiens des résultats différents?

set1 = {1, 2, 3} set2 = {True, False} print(set1 | set2) # {False, 1, 2, 3} print(set2 | set1) #{False, True, 2, 3} 

Pourquoi l’union () ne contient pas tous les éléments

Le 1 et le True sont équivalents et considérés comme des doublons. De même, les 0 et les False sont également équivalents:

 >>> 1 == True True >>> 0 == False True 

Quelle valeur équivalente est utilisée

Lorsque plusieurs valeurs équivalentes sont rencontrées, les ensembles conservent la première vue:

 >>> {0, False} {0} >>> {False, 0} {False} 

Façons de rendre les valeurs distinctes

Pour les traiter séparément, stockez-les simplement dans une paire (value, type) :

 >>> set1 = {(1, int), (2, int), (3, int)} >>> set2 = {(True, bool), (False, bool)} >>> set1 | set2 {(3, ), (1, ), (2, ), (True, ), (False, )} >>> set1 & set2 set() 

Une autre façon de distinguer les valeurs est de les stocker en tant que chaînes:

 >>> set1 = {'1', '2', '3'} >>> set2 = {'True', 'False'} >>> set1 | set2 {'2', '3', 'False', 'True', '1'} >>> set1 & set2 set() 

J’espère que cela éclaircit le mystère et montre la voie à suivre 🙂


Sauvé des commentaires:

C’est la technique standard pour briser l’équivalence entre types croisés (c.-à-d. 0.0 == 0 , True == 1 et Decimal(8.5) == 8.5) . La technique est utilisée dans le module d’expressions régulières de Python 2.7 pour forcer la mise en cache distincte des expressions rationnelles unicode des expressions rationnelles str équivalentes. La technique est également utilisée dans Python 3 pour functools.lru_cache () lorsque le paramètre typé est true.

Si l’OP a besoin d’autre chose que la relation d’équivalence par défaut, une nouvelle relation doit être définie. Selon le cas, cela peut être une insensibilité à la casse pour les chaînes, une normalisation pour unicode, une apparence visuelle (les choses qui sont différentes sont considérées comme différentes), une identité (deux objects distincts sont considérés égaux), une paire valeur / type ou autre fonction qui définit une relation d’équivalence. Compte tenu de l’exemple spécifique des PO, il semblerait qu’il / elle s’attendait soit à une distinction par type, soit à une distinction visuelle.

En Python, False et 0 sont considérés comme équivalents, comme True et 1 . Parce que True et 1 sont considérés comme la même valeur, seul l’un d’entre eux peut être présent dans un ensemble à la même heure. Lequel dépend de l’ordre dans lequel ils sont ajoutés à l’ensemble. Dans la première ligne, set1 est utilisé comme premier ensemble, nous obtenons donc 1 dans l’ensemble résultant. Dans le deuxième jeu, True est dans le premier jeu, donc True est inclus dans le résultat.

Si vous regardez la section https://docs.python.org/3/library/stdtypes.html#boolean-values 4.12.10. Valeurs booléennes:

Les valeurs booléennes sont les deux objects constants False et True . Ils sont utilisés pour représenter des valeurs de vérité (bien que d’autres valeurs puissent également être considérées comme fausses ou vraies). Dans les contextes numériques (par exemple, lorsqu’ils sont utilisés comme argument pour un opérateur arithmétique), ils se comportent comme les entiers 0 et 1 , respectivement.

L’opérateur de comparaison ( == != ) Est défini pour booléen True et False pour correspondre à 1 et 0.

C’est pourquoi, dans l’union définie, quand il vérifie si True est déjà dans le nouvel ensemble, il obtient une réponse véridique:

 >>> True in {1} True >>> 1 in {True} True