Dlaczego „+” nie jest rozumiane przez zestawy Pythona?


90

Chciałbym wiedzieć, dlaczego jest to ważne:

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

ale to nie jest ważne:

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

Czy to dlatego, że „+” może oznaczać zarówno skrzyżowanie, jak i związek?


3
|oznacza związek. O co pytasz?
S.Lott,

13
To dlatego, że Guido wybrał różne operatory dla skrzyżowania i unii.
David Heffernan

3
@David Heffernan, Guido zazwyczaj nie robi rzeczy bez powodu lub przynajmniej jakiejś przewodniej zasady - to właśnie sprawia, że ​​Python jest tak wspaniały.
Mark Ransom

1
@Mark Och, jestem pewien, że zrobił to z dobrego powodu.
David Heffernan,

1
Gdyby ~był tylko operatorem binarnym, mógłbyś mieć |dla + sumę i ~dla różnicy, co jest znacznie bardziej zrównoważone.
Matt Joiner

Odpowiedzi:


109

Zestawy Pythona nie mają implementacji dla +operatora.

Możesz użyć |do zestawu sumy i &do zestawu przecięcia.

Zestawy implementują -jako różnicę zestawów. Możesz również użyć ^dla symetrycznej różnicy zestawów (tj. Zwróci nowy zestaw tylko z obiektami, które pojawiają się w jednym zestawie, ale nie pojawiają się w obu zestawach).


2
Dzięki. Nie wiedziałem o | i &.
badzil

99

Python zdecydował się użyć |zamiast, +ponieważ set union jest pojęciem ściśle związanym z logiczną rozłączeniem; Wektory bitowe (które w Pythonie to po prostu int/ long) definiują tę operację w sekwencji wartości logicznych i nazywają ją „bitową lub”. W rzeczywistości ta operacja jest tak podobna do unii zbioru, że binarne liczby całkowite są czasami nazywane „zestawami bitów”, gdzie elementy zbioru są traktowane jako liczby naturalne.

Bo intjuż definiuje zestaw podobny operatorów jak |, &i ^to było naturalne dla nowszy settyp korzystać z tego samego interfejsu.


7
Myślę, że ta odpowiedź lepiej odpowiada na pytanie „dlaczego”.
Greg Hendershott

1
Prawdopodobnie. +1 za dlaczego. Jednak w pewnym sensie przynajmniej osoba zadająca pytanie wydawała się usatysfakcjonowana tylko wiedzą, jak zrobić zjednoczenie i skrzyżowanie.
Platinum Azure

2
@Platinum: Lubię odpowiadać na faktycznie zadane pytanie, więc gdy pojawi się ktoś, kto ma to pytanie, zobaczy wszystkie rozsądne odpowiedzi; nawet jeśli osoba, która zadała pierwsze pytanie, przeszła dalej. Między nami dwojgiem odpowiadamy dobrze.
SingleNegationElimination

1
@TokenMacGuy: „Ponieważ Python po prostu nie zdefiniował operatora”, odpowiada również dlaczego. :-P
Platinum Azure

15
Nie jestem pewien, czy tak; „Ponieważ jest niebieskie” nie wyjaśnia „Dlaczego niebo jest niebieskie?”
SingleNegationElimination

36

W teorii mnogości symbol + zwykle wskazuje na rozłączny związek dwóch zbiorów. Jeśli A i B są zbiorami, ich rozłączny związek jest zdefiniowany jako zbiór

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

tj. aby skonstruować rozłączny związek, oznaczamy wszystkie elementy A i wszystkie elementy B różnymi tagami (w przykładzie użyłem liczb 1 i 2, ale dwie różne „rzeczy” załatwią sprawę), a następnie suma dwóch wynikowych zbiorów. W powyższym przykładzie użyłem „U” jako sumy zbiorów, aby uczynić ją bardziej podobną do zwykłej notacji matematycznej; poniżej używam notacji Pythona, czyli '|' dla unii i „&” dla przecięcia.

Jeśli A i B są rozłączne, A + B ma korespondencję 1 do 1 z A | B. Jeśli tak nie jest, to wszystkie wspólne elementy x w A i B pojawiają się dwukrotnie w A + B: raz jako (x, 1) i raz jako (x, 2).

Tak więc, ponieważ symbol „+” ma dość dobrze ugruntowane znaczenie jako operacja na zbiorach, uważam za bardzo spójne, że Python nie używa tego symbolu dla unii zbioru lub przecięcia. Prawdopodobnie projektanci Pythona mieli to na uwadze, kiedy wybierali operatory zbiorów.


5
To jest optymalna odpowiedź. Dopóki nie przeczytałem tej odpowiedzi, zastanawiałem się, dlaczego Guido przeciążał |operatora dla ustawionych związków, ale nie udało mi się wyjaśnić, dlaczego Guido uniknął przeciążenia +operatora również dla zestawów zestawu. Przecież takie postępowanie pozwoliłoby zachować ortogonalność, a +operator byłby przeciążony przy dodawaniu list. Ponieważ cechą charakterystyczną Pythona jest zgodność z notacją matematyczną (np. jOznaczanie złożonej składowej liczb zespolonych), ciekawy wybór Guido w końcu ma sens.
Cecil Curry,

23

Jasne, mogli kiedyś +zrobić związek, ale nadal potrzebowaliby symbolu skrzyżowania. |ponieważ zjednoczenie jest symetryczne z &do przecięcia i dlatego jest lepszym wyborem.


10

Ponieważ |oznacza związek i& oznacza skrzyżowanie. Oczywiście nie ma powodu, aby dodawać wielu operatorów do tej samej funkcji.

Powody używania |i &prawdopodobnie wracają do operacji bitowych. Jeśli reprezentujesz zbiór jako bity w liczbie, są to operatory, których użyjesz do wykonania sumy i przecięcia.

+prosty nie jest tak przywiązany do związku i -ma na celu ustanowienie różnicy.


3

Ponieważ różnica w zestawie jest bardzo użyteczną i powszechnie znaną koncepcją, ale nie ma (powszechnie używanej) koncepcji „dodawania zestawu”.


1
Unia? Kiedy ostatnio słyszałeś, jak ktoś powiedział „ustaw dodatek” zamiast „zjednoczenie” lub użyj + zamiast ∪ ?. Czasami +jest definiowany jako dodawanie według członków . Niektórzy używają go do symetrycznej różnicy . Tak czy inaczej, każdy papier, który go używa, nazywa to inaczej lub najpierw definiuje.
Petr Viktorin

1
Ktoś może nazywać to „dodawaniem zestawu”, jeśli nie zna właściwego terminu. Oczywiście ludzie, którzy znają termin „związek”, używają terminu „związek”.
puszysty
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.