Warum gibt es in Pythons Standardbibliotheken keine sortierten Container?

81

Gibt es eine Python-Entwurfsentscheidung (PEP), die verhindert, dass ein sortierter Container zu Python hinzugefügt wird?

( OrderedDictist kein sortierter Behälter, da er nach Einfügereihenfolge sortiert ist.)

Neil G.
quelle
1
wie Sammlungen.OrderedDict?
utdemir
1
Es ist nur schneller. O (1) für Hashmap vs O (log n) für geordnete Menge.
Vartec
18
@utdmr: OrderedDict wird nach Einfügereihenfolge sortiert - nicht nach einem beliebigen Schlüssel, wie bei einem sortierten Container.
Neil G
1
@ Hi-Angel Nein, das ist nicht was sortierter Container bedeutet. ZB
Neil G
1
"sortierter Container ist einer, der Elemente beim Einfügen sortiert". Nicht genau: Ich würde sagen, dass ein sortierter Container ein Container ist, dessen Schnittstelle eine effizient sortierte Iteration und Suche (nach einem beliebigen Schlüssel) aufweist. Ihr Missverständnis ergibt sich aus Ihrer ungewöhnlichen Definition.
Neil G

Antworten:

76

Es ist eine bewusste Designentscheidung von Guido (er war sogar etwas zurückhaltend in Bezug auf das Hinzufügen des collectionsModuls). Sein Ziel ist es, "einen offensichtlichen Weg zu finden", wenn es um die Auswahl von Datentypen für Anwendungen geht.

Das Grundkonzept besteht darin, dass ein Benutzer, der hoch genug ist, um zu erkennen, dass die integrierten Typen nicht die richtige Lösung für sein Problem sind, auch die Aufgabe hat, eine geeignete Bibliothek eines Drittanbieters zu finden.

Angesichts der Tatsache, dass list + sorting, list + heapq und list + bisect viele der Anwendungsfälle abdecken, die ansonsten auf inhärent sortierten Datenstrukturen beruhen würden, und Pakete wie blist existieren, gibt es keinen großen Antrieb, um diesem Bereich mehr Komplexität zu verleihen die Standardbibliothek.

In gewisser Weise ähnelt es der Tatsache, dass die Standardbibliothek kein mehrdimensionales Array enthält, sondern diese Aufgabe an die NumPy-Leute abgibt.

ncoghlan
quelle
2
Danke, ich habe nach den Beweggründen für diese Designentscheidung gesucht. Dies ist genau die Art von Antwort, nach der ich gesucht habe. Mein anfänglicher Instinkt wäre nicht gewesen, die Dinge so zu machen, aber das Argument ist sehr überzeugend.
Neil G
collections.Counterkann als sortierter Satz verwendet werden. Obwohl es möglicherweise nicht effizient ist.
Coderek
1
@coderek: collections.Counterist unsortiert und nicht für die Darstellung einer sortierten Menge geeignet.
user2357112 unterstützt Monica
Aber sollte nicht zumindest das eingebaute Wörterbuch sortiert werden? Das Wörterbuch muss sortiert gespeichert werden, um einen schnellen Zugriff auf Elemente zu ermöglichen. Dies erscheint mir seltsam, dass Sie beim Durchlaufen immer noch irgendwie unsortierte Elemente erhalten.
Hi-Angel
1
@ Hi-Angel dictist eine Hash-Tabelle.
Neil G
80

Es gibt auch ein Python- Modul für sortierte Container , das sortierte Listen-, Diktat- und Set-Typen implementiert. Es ist Blist sehr ähnlich, aber in reinem Python implementiert und in den meisten Fällen schneller .

>>> from sortedcontainers import SortedSet
>>> ss = SortedSet([3, 7, 2, 2])
>>> ss
SortedSet([2, 3, 7])

Es hat auch Funktionen, die für andere Pakete ungewöhnlich sind:

>>> from sortedcontainers import SortedDict
>>> sd = SortedDict((num, num) for num in range(100000))
>>> sd.iloc[-5] # Lookup the fifth-to-last key.
99995

Haftungsausschluss: Ich bin der Autor des Moduls sortierte Container.

GrantJ
quelle
1
Nett! Möglicherweise möchten Sie Ihre Dokumentation aktualisieren, um anzugeben, dass der zugrunde liegende Speicher ein Seil ist .
Neil G
1
@NeilG Danke! Anmerkungen zum Paar: blist ist nicht in reinem Python geschrieben. Die sortierten Mengen-, Listen- und Diktattypen basieren auf dem Blist-Typ, bei dem es sich um einen in C implementierten B + -Baum handelt. Außerdem ist die zugrunde liegende Struktur nicht wirklich ein Seil. Es ähnelt eher einem B + -Baum, hat aber nur eine Knotenebene.
GrantJ
3
Es ist tatsächlich ein großartiges Beispiel dafür, wie Big-O irreführend sein kann. Es würde sich wahrscheinlich um eine Billion Elemente verlangsamen, aber die meisten Menschen haben kein Terabyte Speicher, um sich darüber Sorgen zu machen. Ich habe es in Milliarden von Elementen getestet und es war so schnell wie C-Implementierungen. Durch die Beibehaltung einer so einfachen, listenbasierten Struktur wird auch viel weniger Speicher benötigt.
GrantJ
1
Ja, absolut. Es ist das gleiche Argument, das sie verwenden, um die Verwendung dieser Art von Datenstruktur für Zeichenfolgen zu rechtfertigen, insbesondere für lange Zeichenfolgen, die in einem Editor verwendet werden.
Neil G
2
Wie auch immer, danke, dass du das geschrieben hast. Ich werde es mir merken, wenn ich diese Datenstruktur brauche.
Neil G
11

Es gibt auch das Blist- Modul, das einen sortierten Datentyp enthält :

sortedset(iterable=(), key=None)

>>> from blist import sortedset
>>> my_set = sortedset([3,7,2,2])
sortedset([2, 3, 7]
Adrian
quelle
5

Nicht gerade ein "sortierter Container", aber Sie könnten an dem Halbierungsmodul der Standardbibliothek interessiert sein , das "Unterstützung für die Verwaltung einer Liste in sortierter Reihenfolge bietet, ohne die Liste nach jedem Einfügen sortieren zu müssen".

Steven
quelle
1

Es gibt eine heapqin der Standardbibliothek, sie ist nicht genau sortiert, aber irgendwie. Es gibt auch ein Blist- Paket, das sich jedoch nicht in der Standardbibliothek befindet.

Abt
quelle
-2

Python-Listen sind geordnet. Wenn Sie sie sortieren, bleiben sie so. In Python 2.7 wurde ein OrderedDictTyp hinzugefügt, um ein explizit geordnetes Wörterbuch zu verwalten.

Python hat auch Mengen (eine Sammlung, in der die Mitglieder eindeutig sein müssen), aber per Definition sind sie ungeordnet. Das Sortieren eines Satzes gibt nur a zurück list.

Nathanismus
quelle
8
Vielen Dank, dass Sie sich die Zeit genommen haben, um zu antworten. OrderedDict wird nach Einfügereihenfolge und nicht nach einem beliebigen Schlüssel wie einem sortierten Container sortiert. set ist auch kein sortierter Container.
Neil G
1
Ist btree vielleicht das, wonach Sie suchen? stackoverflow.com/questions/628192#628432
jathanism
danke, btree ist genau das, wonach ich gesucht habe. Ich werde mich für Blist entscheiden, da es in MacPorts ist und eine Reihe praktischer Datenstrukturen hat.
Neil G