Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python Enhancement Proposals

PEP 218 – Hinzufügen eines eingebauten Set-Objekttyps

Autor:
Greg Wilson <gvwilson at ddj.com>, Raymond Hettinger <python at rcn.com>
Status:
Final
Typ:
Standards Track
Erstellt:
31-Jul-2000
Python-Version:
2.2
Post-History:


Inhaltsverzeichnis

Einleitung

Dieser PEP schlägt vor, ein Set-Modul zur Standardbibliothek von Python hinzuzufügen und dann Sets zu einem eingebauten Python-Typ zu machen, wenn dieses Modul weit verbreitet ist. Nachdem erklärt wird, warum Sets wünschenswert sind und warum die gängige Idiomatik, Wörterbücher an ihrer Stelle zu verwenden, unzureichend ist, beschreiben wir, wie wir uns vorstellen, dass eingebettete Sets funktionieren, und dann, wie sich das vorläufige Set-Modul verhalten wird. Der letzte Abschnitt diskutiert die Änderbarkeit (oder auch nicht) von Sets und Set-Elementen und die Lösung, die das Set-Modul implementieren wird.

Begründung

Sets sind eine grundlegende mathematische Struktur und werden in Algorithmenspezifikationen sehr häufig verwendet. Sie werden in Implementierungen viel seltener verwendet, selbst wenn sie die "richtige" Struktur sind. Programmierer verwenden häufig stattdessen Listen, selbst wenn die Ordnungsinformationen in Listen irrelevant sind und Nachschläge nach Wert häufig vorkommen. (Die meisten mittelgroßen C-Programme enthalten eine deprimierende Anzahl von Start-zu-Ende-Suchen durch malloc'd-Vektoren, um festzustellen, ob bestimmte Elemente vorhanden sind oder nicht...)

Programmierern wird oft gesagt, dass sie Sets als Wörterbücher mit "egal welchen" Werten implementieren können. Elemente können zu diesen "Sets" hinzugefügt werden, indem ihnen der "egal welchen" Wert zugewiesen wird; die Mitgliedschaft kann mit dict.has_key getestet werden; und Elemente können mit del gelöscht werden. Die anderen Hauptoperationen auf Sets (Vereinigung, Schnittmenge und Differenz) werden jedoch durch diese Darstellung nicht direkt unterstützt, da ihre Bedeutung für Wörterbücher, die Schlüssel/Wert-Paare enthalten, mehrdeutig ist.

Vorschlag

Das langfristige Ziel dieses PEP ist es, einen eingebauten Set-Typ in Python aufzunehmen. Dieser Typ wird eine ungeordnete Sammlung eindeutiger Werte sein, genau wie ein Wörterbuch eine ungeordnete Sammlung von Schlüssel/Wert-Paaren ist.

Iteration und Comprehensions werden auf die offensichtliche Weise implementiert, so dass

for x in S:

die Elemente von S in beliebiger Reihenfolge durchlaufen, während

set(x**2 for x in S)

ein Set erzeugt wird, das die Quadrate aller Elemente in S enthält. Die Mitgliedschaft wird mit in und not in getestet, und grundlegende Set-Operationen werden durch eine Mischung aus überladenen Operatoren implementiert

| Vereinigung
& Schnittmenge
^ symmetrische Differenz
- asymmetrische Differenz
== != Gleichheits- und Ungleichheitstests
< <= >= > Teilmengen- und Obermengen-Tests

und Methoden

S.add(x) Fügt "x" zum Set hinzu.
S.update(s) Fügt alle Elemente der Sequenz "s" zum Set hinzu.
S.remove(x) Entfernt "x" aus dem Set. Wenn "x" nicht vorhanden ist, löst diese Methode eine LookupError Ausnahme aus.
S.discard(x) Entfernt "x" aus dem Set, wenn es vorhanden ist, oder tut nichts, wenn es nicht vorhanden ist.
S.pop() Entfernt und gibt ein beliebiges Element zurück und löst eine LookupError aus, wenn das Element nicht vorhanden ist.
S.clear() Entfernt alle Elemente aus diesem Set.
S.copy() Erstellt ein neues Set.
s.issuperset() Prüft auf eine Obermengenbeziehung.
s.issubset() Prüft auf eine Teilmengenbeziehung.

und zwei neue eingebaute Konvertierungsfunktionen

set(x) Erstellt ein Set, das die Elemente der Sammlung "x" enthält.
frozenset(x) Erstellt ein unveränderliches Set, das die Elemente der Sammlung "x" enthält.

Anmerkungen

  1. Wir schlagen vor, die Bit-Operatoren "|&" für Schnittmenge und Vereinigung zu verwenden. Während "+" für die Vereinigung intuitiv wäre, ist "*" für die Schnittmenge nicht (sehr wenige der befragten Personen haben erraten, was es korrekt tut).
  2. Wir haben erwogen, "+" zu verwenden, um Elemente zu einem Set hinzuzufügen, anstatt "add". Guido van Rossum wies jedoch darauf hin, dass "+" für andere eingebaute Typen symmetrisch ist (obwohl "*" nicht symmetrisch ist). Die Verwendung von "add" vermeidet auch Verwechslungen zwischen dieser Operation und der Set-Vereinigung.

Set-Notation

Der PEP schlug ursprünglich {1,2,3} als Set-Notation und {-} für das leere Set vor. Die Erfahrung mit Pythons sets.py in Version 2.3 zeigte, dass die Notation nicht notwendig war. Außerdem bestand ein gewisses Risiko, Wörterbücher weniger sofort erkennbar zu machen.

Es wurde auch überlegt, dass die geschweifte Klammerschreibweise Set-Comprehensions unterstützen würde; Python 2.4 lieferte jedoch Generator-Ausdrücke, die dieses Bedürfnis vollständig erfüllten und dies auf eine allgemeinere Weise taten. (Siehe PEP 289 für Details zu Generator-Ausdrücken).

Daher entschied Guido, dass es keine Set-Syntax geben würde; das Thema könnte jedoch für Python 3000 (siehe PEP 3000) wieder aufgegriffen werden.

Historie

Um Erfahrungen mit Sets zu sammeln, wurde in Python 2.3 ein reines Python-Modul eingeführt. Basierend auf dieser Implementierung wurden die Set- und frozenset-Typen in Python 2.4 eingeführt. Die Verbesserungen sind

  • Besserer Hash-Algorithmus für frozensets
  • Kompakteres Pickle-Format (speichert nur eine Elementliste anstelle eines Wörterbuchs von Schlüssel:Wert-Paaren, wobei der Wert immer True ist).
  • Verwendung einer __reduce__ Funktion, so dass tiefes Kopieren automatisch erfolgt.
  • Das BaseSet-Konzept wurde eliminiert.
  • Die union_update() Methode wurde zu update().
  • Die automatische Konvertierung zwischen veränderlichen und unveränderlichen Sets wurde fallen gelassen.
  • Die _repr Methode wurde fallen gelassen (das Bedürfnis wird durch die neue eingebaute Funktion sorted() erfüllt).

Tim Peters glaubt, dass der Konstruktor der Klasse ein einzelnes Sequenz als Argument nehmen und das Set mit den Elementen dieser Sequenz befüllen sollte. Sein Argument ist, dass Programmierer in den meisten Fällen Sets aus bereits vorhandenen Sequenzen erstellen werden, so dass dieser Fall der häufigste sein sollte. Dies würde jedoch erfordern, dass Benutzer eine zusätzliche Klammer für die Initialisierung eines Sets mit bekannten Werten vergessen.

>>> Set((1, 2, 3, 4))       # case 1

Andererseits deutet Feedback von einer kleinen Anzahl von unerfahrenen Python-Nutzern (die alle sehr erfahren mit anderen Sprachen waren) darauf hin, dass eine "klammerfreie" Syntax für sie natürlicher sein wird.

>>> Set(1, 2, 3, 4)         # case 2

Letztendlich haben wir die erste Strategie übernommen, bei der der Initialisierer ein einzelnes iterierbares Argument annimmt.

Änderbarkeit

Die schwierigste Frage, die es in diesem Vorschlag zu lösen galt, war, ob Sets veränderliche Elemente enthalten dürfen. Die Schlüssel eines Wörterbuchs müssen unveränderlich sein, um eine schnelle und zuverlässige Nachschlageunterstützung zu ermöglichen. Obwohl es einfach wäre, unveränderliche Set-Elemente zu verlangen, würde dies Sets von Sets ausschließen (die in Graphenalgorithmen und anderen Anwendungen weit verbreitet sind).

Frühere Entwürfe von PEP 218 hatten nur einen einzigen Set-Typ, aber die sets.py Implementierung in Python 2.3 hat zwei: Set und ImmutableSet. Für Python 2.4 wurden die neuen eingebauten Typen set und frozenset genannt, was etwas weniger umständlich ist.

Im "sets"-Modul sind zwei Klassen implementiert. Instanzen der Set-Klasse können durch Hinzufügen oder Entfernen von Elementen modifiziert werden, und die ImmutableSet-Klasse ist "eingefroren" mit einer unveränderlichen Sammlung von Elementen. Daher kann ein ImmutableSet als Wörterbuchschlüssel oder als Set-Element verwendet werden, kann aber nicht aktualisiert werden. Beide Arten von Sets erfordern, dass ihre Elemente unveränderliche, hashbare Objekte sind. Parallele Kommentare gelten für die eingebauten Typen "set" und "frozenset".


Quelle: https://github.com/python/peps/blob/main/peps/pep-0218.rst

Zuletzt geändert: 2025-02-01 08:55:40 GMT