Объединение 2-х наборов не содержит всех предметов

94

Почему, когда я меняю порядок двух наборов в объединениях ниже, я получаю разные результаты?

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

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

print(set2 | set1)
#{False, True, 2, 3}
Blueplastic
источник

Ответы:

110

Почему union () не содержит всех элементов

Символы 1и Trueэквивалентны и считаются дубликатами. Точно так же 0и Falseэквивалентны:

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

Какое эквивалентное значение используется

Когда встречается несколько эквивалентных значений, наборы сохраняют первое увиденное:

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

Способы сделать ценности отличными

Чтобы их можно было рассматривать как отдельные, просто сохраните их в (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()

Другой способ сделать значения различными - сохранить их в виде строк:

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

Надеюсь, это проясняет тайну и показывает путь вперед :-)


Выручил из комментариев:

Это стандартный метод нарушения эквивалентности перекрестных типов (т.е. 0.0 == 0, True == 1и Decimal(8.5) == 8.5). Этот метод используется в модуле регулярных выражений Python 2.7 для принудительного кэширования регулярных выражений Unicode отдельно от эквивалентных регулярных выражений str. Метод также используется в Python 3 для functools.lru_cache (), когда типизированный параметр истинен.

Если OP нуждается в чем-то отличном от отношения эквивалентности по умолчанию, тогда необходимо определить какое-то новое отношение. В зависимости от варианта использования это может быть нечувствительность к регистру для строк, нормализация для юникода, внешний вид (вещи, которые выглядят по-разному, считаются разными), идентичность (никакие два отдельных объекта не считаются равными), пара значение / тип или некоторые другие функция, определяющая отношение эквивалентности. Учитывая конкретный пример ОП, может показаться, что он / она ожидал различий по типу или визуальных различий.

Раймонд Хеттингер
источник
20

В Python Falseи 0считаются эквивалентными, как Trueи 1. Поскольку Trueи 1считаются одним и тем же значением, только одно из них может присутствовать в наборе одновременно. Какой из них зависит от того, в каком порядке они добавляются в набор. В первой строке set1используется как первый набор, поэтому мы попадаем 1в результирующий набор. Во втором наборе, Trueвходит в первый набор, поэтому Trueвключается в результат.

mcslane
источник
6

Если вы посмотрите https://docs.python.org/3/library/stdtypes.html#boolean-values раздел 4.12.10. Логические значения:

Логические значения - это два постоянных объекта False и True . Они используются для представления значений истинности (хотя другие значения также могут считаться ложными или истинными). В числовом контексте (например, при использовании в качестве аргумента арифметического оператора) они ведут себя как целые числа 0 и 1 соответственно.

задница
источник
4

Оператор сравнения ( ==, !=) определен для логического значения Trueи Falseсоответствует 1 и 0.

Вот почему в объединении наборов, когда он проверяет, Trueнаходится ли он уже в новом наборе, он получает правдивый ответ:

>>> True in {1}
True
>>> 1 in {True}
True
Уриил
источник