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}
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.
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.
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.
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