Союз 2 комплектов не содержит все предметы
Почему, когда я меняю порядок двух наборов в союзах ниже, я получаю разные результаты?
set1 = {1, 2, 3}
set2 = {True, False}
print(set1 | set2)
# {False, 1, 2, 3}
print(set2 | set1)
#{False, True, 2, 3}
4 ответа
Почему 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 для принудительного кэширования регулярных выражений юникода в отличие от других эквивалентных регулярных выражений str. Техника также используется в Python 3 для functools.lru_cache(), когда типизированный параметр имеет значение true.
Если OP требуется нечто иное, чем отношение эквивалентности по умолчанию, то необходимо определить какое-то новое отношение. В зависимости от варианта использования это может быть нечувствительность к регистру для строк, нормализация для юникода, внешний вид (вещи, которые выглядят по-разному, считаются разными), идентичность (никакие два разных объекта не считаются равными), пара значение / тип или некоторые другие функция, которая определяет отношение эквивалентности. Учитывая конкретный пример ФП, может показаться, что он / она ожидал либо различия по типу, либо визуального различия.
В Python False
а также 0
считаются эквивалентными, как и True
а также 1
, Так как True
а также 1
считаются одним и тем же значением, только один из них может присутствовать в наборе одновременно. Какой из них зависит от того, в каком порядке они добавляются в набор. В первой строке set1
используется в качестве первого набора, поэтому мы получаем 1
в результирующем наборе. Во втором сете True
в первом сете, так True
включен в результат.
Если вы посмотрите на https://docs.python.org/3/library/stdtypes.html раздел 4.12.10. Булевы значения:
Логические значения - это два постоянных объекта False и True. Они используются для представления истинных значений (хотя другие значения также могут считаться ложными или истинными). В числовом контексте (например, при использовании в качестве аргумента арифметического оператора) они ведут себя как целые числа 0 и 1 соответственно.
Оператор сравнения (==
, !=
) определяется для логического True
а также False
соответствовать 1 и 0.
Вот почему в объединении множеств, когда он проверяет, True
уже в новом наборе, он получает правдивый ответ:
>>> True in {1}
True
>>> 1 in {True}
True