União de 2 conjuntos não contém todos os itens

94

Por que, ao alterar a ordem dos dois conjuntos nos sindicatos abaixo, obtenho resultados diferentes?

set1 = {1, 2, 3}
set2 = {True, False}

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

print(set2 | set1)
#{False, True, 2, 3}
Blueplastic
fonte

Respostas:

110

Por que o sindicato () não contém todos os itens

Os 1e Truesão equivalentes e considerados duplicados. Da mesma forma, 0e também Falsesão equivalentes:

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

Qual valor equivalente é usado

Quando vários valores equivalentes são encontrados, os conjuntos mantêm o primeiro visto:

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

Maneiras de tornar os valores distintos

Para que sejam tratados como distintos, basta armazená-los em um (value, type)par:

>>> 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()

Outra maneira de tornar os valores distintos é armazená-los como strings:

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

Espero que isso esclareça o mistério e mostre o caminho a seguir :-)


Resgatado dos comentários:

Esta é a técnica padrão para a quebra do tipo cruzado equivalência (isto é 0.0 == 0, True == 1, e Decimal(8.5) == 8.5). A técnica é utilizada no módulo expressão regular Python 2,7 de expressões regulares a força Unicode para colocar em cache distintamente a partir de expressões regulares str outro modo equivalentes. A técnica é também usada em Python 3 para functools.lru_cache () quando o parâmetro digitado é verdadeiro.

Se o OP precisa de algo diferente da relação de equivalência padrão, alguma nova relação precisa ser definida. Dependendo do caso de uso, isso pode ser insensibilidade a maiúsculas e minúsculas para strings, normalização para Unicode, aparência visual (coisas que parecem diferentes são consideradas diferentes), identidade (dois objetos distintos não são considerados iguais), um par de valor / tipo ou algum outro função que define uma relação de equivalência. Dado o exemplo específico de POs, parece que ele esperava uma distinção por tipo ou distinção visual.

Raymond Hettinger
fonte
20

Em Python, Falsee 0são considerados equivalentes, assim como Truee 1. Como Truee 1são considerados o mesmo valor, apenas um deles pode estar presente em um conjunto ao mesmo tempo. Qual deles depende da ordem em que são adicionados ao conjunto. Na primeira linha, set1é usado como o primeiro conjunto, então obtemos 1o conjunto resultante. No segundo conjunto, Trueestá no primeiro conjunto, portanto, Trueé incluído no resultado.

mcslane
fonte
6

Se você olhar a https://docs.python.org/3/library/stdtypes.html#boolean-values seção 4.12.10. Valores booleanos:

Os valores booleanos são os dois objetos constantes, False e True . Eles são usados ​​para representar valores verdadeiros (embora outros valores também possam ser considerados falsos ou verdadeiros). Em contextos numéricos (por exemplo, quando usados ​​como argumento para um operador aritmético), eles se comportam como os inteiros 0 e 1 , respectivamente.

chocksaway
fonte
4

O operador de comparação ( ==, !=) é definido como booleano Truee Falsepara corresponder a 1 e 0.

É por isso que, na união do conjunto, ao verificar se já Trueestá no novo conjunto, obtém uma resposta verdadeira:

>>> True in {1}
True
>>> 1 in {True}
True
Uriel
fonte