Jak to się dzieje, że kiedy zmieniam kolejność dwóch zestawów w poniższych złączach, otrzymuję różne wyniki?
set1 = {1, 2, 3}
set2 = {True, False}
print(set1 | set2)
# {False, 1, 2, 3}
print(set2 | set1)
#{False, True, 2, 3}
źródło
Jak to się dzieje, że kiedy zmieniam kolejność dwóch zestawów w poniższych złączach, otrzymuję różne wyniki?
set1 = {1, 2, 3}
set2 = {True, False}
print(set1 | set2)
# {False, 1, 2, 3}
print(set2 | set1)
#{False, True, 2, 3}
Elementy 1
i True
są równoważne i uważane za duplikaty. Podobnie 0
i False
są również równoważne:
>>> 1 == True
True
>>> 0 == False
True
W przypadku napotkania wielu równoważnych wartości zestawy zachowują pierwszą widoczną:
>>> {0, False}
{0}
>>> {False, 0}
{False}
Aby traktować je jako odrębne, po prostu zapisz je w (value, type)
parze:
>>> 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()
Innym sposobem na odróżnienie wartości jest przechowywanie ich jako ciągów:
>>> set1 = {'1', '2', '3'}
>>> set2 = {'True', 'False'}
>>> set1 | set2
{'2', '3', 'False', 'True', '1'}
>>> set1 & set2
set()
Mam nadzieję, że to wyjaśnia tajemnicę i wskazuje drogę naprzód :-)
Uratowany z komentarzy:
Jest to standardowa technika łamania krzyżowych równoważności (tj 0.0 == 0
, True == 1
iDecimal(8.5) == 8.5)
. Technika ta jest stosowana w zwykły moduł ekspresyjny Python 2,7 do regexes siła unikodzie na buforowane wyraźnie od równoważna regexes str. Technika ta jest również stosowana w Pythonie 3 dla functools.lru_cache (), gdy wpisany parametr ma wartość true.
Jeśli PO potrzebuje czegoś innego niż domyślna relacja równoważności, należy zdefiniować nową relację. W zależności od przypadku użycia, może to być niewrażliwość na wielkość liter dla ciągów znaków, normalizacja dla Unicode, wygląd wizualny (rzeczy, które wyglądają inaczej są uważane za różne), tożsamość (żadne dwa różne obiekty nie są uważane za równe), para wartość / typ lub inne funkcja definiująca relację równoważności. Biorąc pod uwagę konkretny przykład PO, wydaje się, że spodziewał się on rozróżnienia według typu lub wizualnego.
W Pythonie False
i 0
są uważane za równoważne, podobnie jak True
i 1
. Ponieważ True
i 1
są uważane za tę samą wartość, tylko jeden z nich może występować w zestawie w tym samym czasie. Który z nich zależy od kolejności, w jakiej są one dodawane do zestawu. W pierwszej linii set1
jest używany jako pierwszy zestaw, więc otrzymujemy 1
wynikowy zestaw. W drugim zestawie True
znajduje się w pierwszym zestawie, więc True
jest uwzględniany w wyniku.
Jeśli spojrzysz na https://docs.python.org/3/library/stdtypes.html#boolean-values sekcja 4.12.10. Wartości logiczne:
Wartości logiczne to dwa stałe obiekty False i True . Służą do reprezentowania wartości prawdy (chociaż inne wartości można również uznać za fałszywe lub prawdziwe). W kontekstach liczbowych (na przykład, gdy są używane jako argument operatora arytmetycznego), zachowują się jak odpowiednio liczby całkowite 0 i 1 .
Operator porównania ( ==
, !=
) jest zdefiniowany dla wartości logicznych True
iFalse
dopasowany do 1 i 0.
Dlatego w set union, gdy sprawdza, czy True
jest już w nowym zestawie, otrzymuje prawdziwą odpowiedź:
>>> True in {1}
True
>>> 1 in {True}
True