Union de 2 ensembles ne contient pas tous les éléments

Comment se fait-il que lorsque je change l'ordre des deux ensembles dans les unions ci-dessous, j'obtienne 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}
94
demandé sur Raymond Hettinger 2017-06-12 02:29:48

4 réponses

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

Le 1 et True sont équivalents et considérés comme des doublons. De même, les 0 et 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 qu'ils soient traités comme distincts, il suffit de les stocker dans une paire (value, type):

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

Un autre la façon de rendre les valeurs distinctes est de les stocker sous forme de chaînes:

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

Espérons que cela éclaircit le mystère et montre la voie à suivre: -)


Sauvé des commentaires:

C'est la technique standard pour briser l'équivalence de type croisé (c'est-à-dire 0.0 == 0, True == 1, et Decimal(8.5) == 8.5). La technique est utilisée dans le module d'expression régulière de python 2.7 pour forcer les expressions rationnelles unicode à être mises en cache distinctement des expressions rationnelles str autrement équivalentes. La technique est également utilisée en Python 3 pour functools.lru_cache() lorsque le paramètre typé est vrai.

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

112
répondu Raymond Hettinger 2017-06-23 15:27:49

En Python, False et 0 sont considérés comme équivalents, comme le sont True et 1. Parce que True et 1 sont considérés comme la même valeur, un seul d'entre eux peut être présent dans un ensemble a en même temps. 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, donc nous obtenons 1 dans l'ensemble résultant. Dans le deuxième set, True est dans le premier set, donc True est inclus dans le résultat.

21
répondu mcslane 2017-06-12 20:52:07

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

Valeurs Booléennes sont les deux objets constants False et True. Ils sont utilisés pour représenter des valeurs de vérité (bien que d'autres valeurs peuvent é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.

7
répondu chocksaway 2017-06-11 23:45:10

L'opérateur de comparaison (==, !=) est défini pour boolean True et False pour correspondre à 1 et 0.

C'est pourquoi, dans l'union set, 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
5
répondu Uriel 2017-06-13 21:07:02