Warum wird '+' von Python-Sets nicht verstanden?

85

Ich würde gerne wissen, warum dies gültig ist:

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

Dies ist jedoch nicht gültig:

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

Liegt es daran, dass '+' sowohl Schnittmenge als auch Vereinigung bedeuten kann?

Badzil
quelle
3
|bedeutet Vereinigung. Was fragst du?
S.Lott
13
Das liegt daran, dass Guido verschiedene Operatoren für Kreuzung und Vereinigung ausgewählt hat.
David Heffernan
3
@ David Heffernan, Guido macht Dinge normalerweise nicht ohne Grund oder zumindest ohne Leitprinzip - das macht Python so großartig.
Mark Ransom
1
@ Mark Oh, ich bin mir ziemlich sicher, dass er es aus einem guten Grund getan hat.
David Heffernan
1
Wenn nur ~ein binärer Operator wäre, dann könnten Sie |für + union und ~für Differenz haben, was viel ausgeglichener ist.
Matt Joiner

Antworten:

101

Python-Sets haben keine Implementierung für den +Operator.

Sie können |für die Set-Vereinigung und &für die Set-Schnittmenge verwenden.

Sets werden -als Setdifferenz implementiert . Sie können auch die ^symmetrische Mengendifferenz verwenden (dh es wird eine neue Menge mit nur den Objekten zurückgegeben, die in einer Menge erscheinen, aber nicht in beiden Mengen).

Platinum Azure
quelle
2
Vielen Dank. Ich wusste nichts über | und &.
Badzil
97

Python entschied sich für die Verwendung |anstelle von, +weil set union ein Konzept ist, das eng mit der booleschen Disjunktion zusammenhängt. Bitvektoren (die in Python nur int/ sind long) definieren diese Operation über eine Folge von Booleschen Werten und nennen sie "bitweise oder". Tatsächlich ist diese Operation der Mengenvereinigung so ähnlich, dass binäre Ganzzahlen manchmal auch als "Bitmengen" bezeichnet werden, wobei die Elemente in der Menge als natürliche Zahlen angenommen werden.

Da intbereits Set-wie Operatoren wie definiert |, &und ^es war natürlich für die neuere setArt die gleiche Schnittstelle zu verwenden.

SingleNegationElimination
quelle
7
Ich denke, diese Antwort spricht das "Warum" in der Frage besser an.
Greg Hendershott
1
Wahrscheinlich. +1 für das Warum. In gewisser Hinsicht schien zumindest der Fragesteller damit zufrieden zu sein, nur zu wissen, wie man Vereinigung und Überschneidung macht.
Platinum Azure
2
@Platinum: Ich beantworte gerne die tatsächlich gestellte Frage. Wenn also jemand anderes vorbeikommt, der diese Frage hat, kann er alle vernünftigen Antworten sehen. selbst wenn die Person, die die ursprüngliche Frage gestellt hat, weitergezogen ist. Zwischen uns beiden antworten wir gut.
SingleNegationElimination
1
@TokenMacGuy: "Weil Python den Operator einfach nicht definiert hat" beantwortet auch das Warum. :-P
Platinum Azure
15
Ich bin mir nicht sicher, ob es so ist. "Weil es blau ist" erklärt nicht "Warum ist der Himmel blau?"
SingleNegationElimination
35

In der Mengenlehre zeigt das + -Symbol normalerweise die disjunkte Vereinigung zweier Mengen an. Wenn A und B Mengen sind, wird ihre disjunkte Vereinigung als Menge definiert

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

Das heißt, um die disjunkte Vereinigung zu konstruieren, markieren wir alle Elemente von A und alle Elemente von B mit unterschiedlichen Tags (im Beispiel habe ich die Zahlen 1 und 2 verwendet, aber zwei verschiedene "Dinge" würden den Job erledigen) und nehmen dann die Vereinigung der beiden resultierenden Mengen. Im obigen Beispiel habe ich 'U' für die Mengenvereinigung verwendet, um sie der üblichen mathematischen Notation ähnlicher zu machen. unten benutze ich die Python-Notation, dh '|' für Vereinigung und '&' für Kreuzung.

Wenn A und B disjunkt sind, hat A + B eine 1: 1-Entsprechung mit A | B. Wenn dies nicht der Fall ist, erscheinen alle gemeinsamen Elemente x in A & B zweimal in A + B: einmal als (x, 1) und einmal als (x, 2).

Da das Symbol '+' als Mengenoperation eine recht gut etablierte Bedeutung hat, finde ich es sehr konsistent, dass Python dieses Symbol nicht für die Vereinigung oder Schnittmenge von Mengen verwendet. Wahrscheinlich hatten Python-Designer dies im Sinn, als sie Set-Operatoren auswählten.

Giorgio
quelle
4
Dies ist die optimale Antwort. Bis ich diese Antwort gelesen habe, habe ich herausgefunden, warum Guido den |Betreiber für festgelegte Gewerkschaften überlastet hat, aber nicht verstanden, warum Guido es vermieden hat, den +Betreiber auch für festgelegte Gewerkschaften zu überlasten . Schließlich hätte dies die Orthogonalität bewahrt, wenn der +Operator für das Hinzufügen von Listen überladen wäre. Da Pythons Kennzeichen die Übereinstimmung mit der mathematischen Notation ist (z. B. die jBezeichnung der komplexen Komponente komplexer Zahlen), ist Guidos merkwürdige Wahl schließlich sinnvoll.
Cecil Curry
23

Sicher, sie hätten früher +eine Gewerkschaft bilden können, brauchen dann aber immer noch ein Symbol für die Kreuzung. |denn Vereinigung ist symmetrisch mit &Schnittmenge und trifft daher eine bessere Wahl.

Mark Ransom
quelle
10

Weil |bedeutet Vereinigung und &bedeutet Kreuzung. Es gibt eindeutig keinen Grund, mehrere Operatoren für dieselbe Funktion hinzuzufügen.

Die Gründe für die Verwendung |und gehen &wahrscheinlich auf bitweise Operationen zurück. Wenn Sie eine Menge als Bits in einer Zahl darstellen, sind dies die Operatoren, die Sie zum Vereinigen und Überschneiden verwenden würden.

+einfach ist nicht so gewerkschaftsgebunden und -soll Differenz setzen.

Winston Ewert
quelle
3

Weil Mengenunterschiede ein sehr nützliches und allgemein bekanntes Konzept sind, es aber kein (allgemein verwendetes) Konzept der „Mengenaddition“ gibt.

Petr Viktorin
quelle
1
Union? Wann haben Sie das letzte Mal jemanden sagen hören „Add add“ anstelle von „union“ oder + anstelle von ∪ verwenden?. Wird manchmal +als mitgliedsbezogene Addition definiert . Einige verwenden es für symmetrische Unterschiede . In jedem Fall nennt jedes Papier, das es verwendet, es etwas anderes oder definiert es zuerst.
Petr Viktorin
1
Jemand könnte es als "Set Addition" bezeichnen, wenn er den richtigen Begriff nicht kennt. Offensichtlich verwenden Leute, die den Begriff "Gewerkschaft" kennen, den Begriff "Gewerkschaft".
flauschig