Почему "+" не понимается наборами Python?


90

Я хотел бы знать, почему это действительно так:

set(range(10)) - set(range(5))

но это неверно:

set(range(10)) + set(range(5))

Это потому, что «+» может означать как пересечение, так и объединение?


3
|означает союз. Что ты спрашиваешь?
S.Lott

13
Это потому, что Гвидо выбрал разные операторы для пересечения и объединения.
Дэвид Хеффернан

3
@ Дэвид Хеффернан, Гвидо обычно не делает ничего без причины или хотя бы какого-то руководящего принципа - вот что делает Python таким замечательным.
Марк Рэнсом

1
@Mark О, я уверен, что он сделал это по уважительной причине.
Дэвид Хеффернан

1
Если бы был только ~бинарный оператор, то вы могли бы иметь |для + union и ~для разницы, что гораздо более сбалансировано.
Мэтт Джойнер

Ответы:


109

В наборах Python нет реализации для +оператора.

Вы можете использовать |для объединения множеств и &для пересечения множеств.

Наборы реализуются -как разница наборов. Вы также можете использовать ^для симметричного набора разность (т. Е. Он вернет новый набор только с объектами, которые появляются в одном наборе, но не появляются в обоих наборах).


2
Спасибо. Я не знал о | а также &.
badzil 07

99

Python решил использовать |вместо этого, +потому что set union - это концепция, которая тесно связана с логической дизъюнкцией; Битовые векторы (которые в Python - это просто int/ long) определяют эту операцию для последовательности логических значений и называют ее «побитовым или». На самом деле эта операция настолько похожа на объединение множеств, что двоичные целые числа иногда также называют «битовыми наборами», где элементы в наборе считаются натуральными числами.

Поскольку intуже определены операторы, подобные множеству, как |, &и ^, для нового setтипа было естественно использовать тот же интерфейс.


7
Я думаю, что этот ответ лучше отвечает «почему» в вопросе.
Грег Хендершотт

1
Наверное. +1 за почему. В каком-то смысле, по крайней мере, задававший вопрос, казалось, был удовлетворен тем, что просто знал, как объединить и пересечь.
Platinum Azure

2
@Platinum: мне нравится отвечать на действительно заданный вопрос, поэтому, когда приходит кто-то, у кого есть этот вопрос, он может увидеть все разумные ответы; даже если человек, задавший исходный вопрос, ушел. Мы вдвоем хорошо на это отвечаем.
SingleNegationElimination

1
@TokenMacGuy: «Потому что Python просто не определил оператор» также отвечает на вопрос, почему. :-P
Платиновая лазурь

15
Я не уверен, что это так; «Потому что оно голубое» не объясняет «Почему небо голубое?»
SingleNegationElimination 08

36

В теории множеств символ + обычно указывает на несвязное объединение двух множеств. Если A и B - множества, их непересекающееся объединение определяется как множество

A + B = {(a, 1) | a in A} U {(b, 2) | b in B}

то есть, чтобы построить непересекающееся объединение, мы помечаем все элементы A и все элементы B разными тегами (в примере я использовал числа 1 и 2, но любые две разные «вещи» будут делать работу), а затем берем объединение двух результирующих множеств. В приведенном выше примере я использовал «U» для объединения множеств, чтобы сделать его более похожим на обычную математическую нотацию; ниже я использую нотацию Python, т.е. '|' для объединения и '&' для пересечения.

Если A и B не пересекаются, A + B имеет соответствие 1: 1 с A | B. Если это не так, то все общие элементы x в A и B появляются дважды в A + B: один раз как (x, 1) и один раз как (x, 2).

Итак, поскольку символ '+' имеет довольно устоявшееся значение как операция над множеством, я считаю очень последовательным, что Python не использует этот символ для объединения или пересечения множеств. Вероятно, разработчики Python имели это в виду, когда выбирали операторы множества.


5
Это оптимальный ответ. До того, как я прочитал этот ответ, я задумался, почему Guido перегрузил |оператор для объединений множеств, но не смог понять, почему Guido также избегал перегрузки +оператора для объединений множеств. В конце концов, это сохранило бы ортогональность с +оператором, перегруженным для добавления в список. Поскольку отличительной чертой Python является соответствие математическим обозначениям (например, jобозначение комплексной составляющей комплексных чисел), любопытный выбор Гвидо, наконец, имеет смысл.
Сесил Карри

23

Конечно, они могли использовать +объединение, но тогда все равно понадобится символ пересечения. |для объединения симметрично с &для пересечения и поэтому делает лучший выбор.


10

Потому что |означает союз и &означает пересечение. Очевидно, нет причин добавлять несколько операторов для одной и той же функции.

Причины использования |и , &вероятно , восходят к поразрядным операциям. Если вы представляете набор в виде битов числа, это операторы, которые вы использовали бы для объединения и пересечения.

+simple не так привязан к объединению, а -устанавливает разницу.


3

Потому что разница наборов - очень полезная и широко известная концепция, но нет (универсально используемой) концепции «сложения наборов».


1
Союз? Когда вы в последний раз слышали, чтобы кто-то сказал «сложить сложение» вместо «объединить» или использовать + вместо ∪? Иногда +определяется как пополнение . Некоторые используют его для симметричной разницы . В любом случае, любая бумага, в которой он используется, либо называет это как-то иначе, либо сначала определяет это.
Петр Викторин

1
Кто-то может назвать это «добавлением множества», если не знает правильного термина. Очевидно, люди, знающие термин «союз», используют термин «союз».
пушистый
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.