Я хотів би знати, чому це дійсно:
set(range(10)) - set(range(5))
але це недійсно:
set(range(10)) + set(range(5))
Це тому, що "+" може означати як перетин, так і об'єднання?
Я хотів би знати, чому це дійсно:
set(range(10)) - set(range(5))
але це недійсно:
set(range(10)) + set(range(5))
Це тому, що "+" може означати як перетин, так і об'єднання?
~
двійковий оператор, то ви могли б мати як |
для + об'єднання, так і ~
для різниці, яка є набагато більш збалансованою.
Відповіді:
Набори Python не мають реалізації для +
оператора.
Можна використовувати |
для об'єднання множин та &
для перетину множин.
Набори реалізують -
як встановлену різницю. Ви також можете використовувати ^
для симетричної різниці наборів (тобто вона поверне новий набір лише з об'єктами, які відображаються в одному наборі, але не відображаються в обох наборах).
Python вирішив використовувати |
замість того, +
що об'єднання множин - це поняття, яке тісно пов'язане з булевою диз'юнкцією; Бітові вектори (які в python - це просто int
/ long
) визначають цю операцію в послідовності булевих значень і називають її "побітовим або". Насправді ця операція настільки схожа на об'єднання множин, що двійкові цілі числа іноді також називають "бітовими наборами", де елементами у множині прийнято вважати натуральні числа.
Оскільки int
оператори, подібні до набору, вже визначають як |
, &
і ^
для нового set
типу було природно використовувати той самий інтерфейс.
У теорії множин символ + зазвичай вказує на неперервний союз двох множин. Якщо 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 мали це на увазі, коли обирали оператори набору.
|
оператора для наборів об'єднань, але не зміг зрозуміти, чому Гвідо також уникнув перевантаження +
оператора для об'єднань множин. Зрештою, це призвело б до збереження ортогональності з +
перевантаженням оператора для додавання списку. Оскільки відмітною ознакою Пітона є відповідність математичним позначенням (наприклад, j
позначення складної складової комплексних чисел), допитливий вибір Гвідо нарешті має сенс.
Звичайно, вони могли б +
робити об’єднання, але тоді все одно знадобився б символ для перетину. |
для об'єднання є симетричним &
для перетину і, отже, робить кращий вибір.
Тому що |
означає союз і &
означає перетин. Очевидно, немає жодної причини додавати кілька операторів для однієї функції.
Причини використання |
та, &
ймовірно, сягають побітових операцій. Якщо ви представляєте набір як біти числа, це ті оператори, які ви використовували б для об'єднання та перетину.
+
просте не настільки прив’язане до об’єднання і -
полягає у встановленні різниці.
Оскільки різниця в множинах є дуже корисним і загальновідомим поняттям, але не існує (загальновживаного) поняття „додавання множин“.
+
це визначається як додавання членів . Деякі використовують його для симетричної різниці . У будь-якому випадку, будь-який папір, який використовує його, або називає це інакше, або визначає його першим.
|
означає союз. Що ти питаєш?