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}
fonte
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}
Os 1
e True
são equivalentes e considerados duplicados. Da mesma forma, 0
e também False
são equivalentes:
>>> 1 == True
True
>>> 0 == False
True
Quando vários valores equivalentes são encontrados, os conjuntos mantêm o primeiro visto:
>>> {0, False}
{0}
>>> {False, 0}
{False}
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.
Em Python, False
e 0
são considerados equivalentes, assim como True
e 1
. Como True
e 1
sã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 1
o conjunto resultante. No segundo conjunto, True
está no primeiro conjunto, portanto, True
é incluído no resultado.
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.
O operador de comparação ( ==
, !=
) é definido como booleano True
e False
para corresponder a 1 e 0.
É por isso que, na união do conjunto, ao verificar se já True
está no novo conjunto, obtém uma resposta verdadeira:
>>> True in {1}
True
>>> 1 in {True}
True