782 Stimmen

Gibt es in Python eine geordnete Menge?

Python hat eine geordnetes Wörterbuch . Wie wäre es mit einem geordneten Satz?

26 Stimmen

Was ist mit dem Converse, einer Tasche voller Dinge? (ungeordnet und nicht einmalig)

28 Stimmen

@wim collections.Counter ist die Tasche von Python.

4 Stimmen

Was passiert, wenn etwas zweimal hinzugefügt wird? Wie sollte die Position lauten?

28voto

GrantJ Punkte 7350

Wenn Sie die geordnete Menge verwenden, um eine sortierte Reihenfolge beizubehalten, sollten Sie die Implementierung einer sortierten Menge von PyPI verwenden. Die sortierte Container Modul bietet eine SortedSet für genau diesen Zweck. Einige Vorteile: reines Python, schnelle As-C-Implementierungen, 100 %ige Abdeckung durch Unit-Tests, stundenlange Stresstests.

Die Installation von PyPI ist mit pip einfach:

pip install sortedcontainers

Beachten Sie, dass, wenn Sie nicht in der Lage sind pip install zu verwenden, ziehen Sie einfach die Dateien sortedlist.py und sortedset.py aus dem Verzeichnis Open-Source-Repository .

Nach der Installation können Sie einfach:

from sortedcontainers import SortedSet
help(SortedSet)

Das sortedcontainers-Modul verwaltet auch eine Leistungsvergleich mit mehreren alternativen Implementierungen.

Für den Kommentar, der nach dem Python-Datentyp bag fragte, gibt es alternativ eine SortierteListe Datentyp, der zur effizienten Implementierung einer Tasche verwendet werden kann.

0 Stimmen

Beachten Sie, dass die SortedSet Klasse erfordert, dass die Mitglieder vergleichbar und hashfähig sind.

7 Stimmen

@gsnedders Die Bausteine set y frozenset erfordern ebenfalls, dass die Elemente hashfähig sind. Die vergleichbare Bedingung ist der Zusatz für SortedSet aber es ist auch eine offensichtliche Einschränkung.

2 Stimmen

Wie der Name schon sagt, wird damit keine Ordnung aufrechterhalten. Es ist nichts anderes als sorted(set([sequence])), was besser ist?

19voto

bustawin Punkte 595

Wie andere Antworten erwähnen, ist das Diktat in Python 3.7+ per Definition geordnet. Anstatt die Unterklasse OrderedDict können wir die Unterklasse abc.collections.MutableSet ou typing.MutableSet mit den Schlüsseln des Diktats, um unsere Werte zu speichern.

import itertools
import typing

T = typing.TypeVar("T")

class OrderedSet(typing.MutableSet[T]):
    """A set that preserves insertion order by internally using a dict."""

    def __init__(self, iterable: typing.Iterator[T]):
        self._d = dict.fromkeys(iterable)

    def add(self, x: T) -> None:
        self._d[x] = None

    def discard(self, x: T) -> None:
        self._d.pop(x, None)

    def __contains__(self, x: object) -> bool:
        return self._d.__contains__(x)

    def __len__(self) -> int:
        return self._d.__len__()

    def __iter__(self) -> typing.Iterator[T]:
        return self._d.__iter__()

    def __str__(self):
        return f"{{{', '.join(str(i) for i in self)}}}"

    def __repr__(self):
        return f"<OrderedSet {self}>"

Dann eben:

x = OrderedSet([1, 2, -1, "bar"])
x.add(0)
assert list(x) == [1, 2, -1, "bar", 0]

Ich habe diesen Code mit einigen Tests in eine kleine Bibliothek eingefügt so kann jeder einfach pip install es.

2 Stimmen

Verwenden Sie es nicht so, wie es ist. discard sollten niemals ein KeyError . Beachten Sie auch, dass dies keine sinnvolle __repr__

0 Stimmen

@JasonForbes Sie haben Recht - in der Tat haben wir Ihre Kommentare in dem verlinkten Repo angesprochen. Daher habe ich diese Korrekturen in diese Antwort aufgenommen. Vielen Dank für den Hinweis! :-)

13voto

Berislav Lopac Punkte 15229

Für den Fall, dass Sie bereits Pandas in Ihrem Code verwenden, ist dessen Index Objekt verhält sich ziemlich wie eine geordnete Menge, wie in dieser Artikel .

Beispiele aus dem Artikel:

indA = pd.Index([1, 3, 5, 7, 9])
indB = pd.Index([2, 3, 5, 7, 11])

indA & indB  # intersection
indA | indB  # union
indA - indB  # difference
indA ^ indB  # symmetric difference

0 Stimmen

Können Sie dieser Antwort ein Beispiel beifügen? Links neigen dazu, nach einiger Zeit kaputt zu gehen.

1 Stimmen

Für die Differenz zwischen den Sätzen, müssen Sie eigentlich die indA.difference(indB) Das Minus-Zeichen führt eine Standard-Subtraktion durch.

3 Stimmen

Es ist wichtig zu beachten, dass pd.Index lässt doppelte Elemente zu, was man von einem aktuellen Python-Programm nicht erwarten würde set .

10voto

Michael Lenzen Punkte 792

Ich bin zwar etwas spät dran, aber ich habe einen Kurs geschrieben setlist als Teil von collections-extended die sowohl die Sequence y Set

>>> from collections_extended import setlist
>>> sl = setlist('abracadabra')
>>> sl
setlist(('a', 'b', 'r', 'c', 'd'))
>>> sl[3]
'c'
>>> sl[-1]
'd'
>>> 'r' in sl  # testing for inclusion is fast
True
>>> sl.index('d')  # so is finding the index of an element
4
>>> sl.insert(1, 'd')  # inserting an element already in raises a ValueError
ValueError
>>> sl.index('d')
4

GitHub: https://github.com/mlenzen/collections-extended

Dokumentation: http://collections-extended.lenzm.net/en/latest/

PyPI: https://pypi.python.org/pypi/collections-extended

10voto

AbstProcDo Punkte 17041

Es gibt keine OrderedSet in der offiziellen Bibliothek. Ich habe ein umfassendes Cheatsheet mit allen Datenstrukturen zu Ihrer Information erstellt.

DataStructure = {
    'Collections': {
        'Map': [
            ('dict', 'OrderDict', 'defaultdict'),
            ('chainmap', 'types.MappingProxyType')
        ],
        'Set': [('set', 'frozenset'), {'multiset': 'collection.Counter'}]
    },
    'Sequence': {
        'Basic': ['list', 'tuple', 'iterator']
    },
    'Algorithm': {
        'Priority': ['heapq', 'queue.PriorityQueue'],
        'Queue': ['queue.Queue', 'multiprocessing.Queue'],
        'Stack': ['collection.deque', 'queue.LifeQueue']
        },
    'text_sequence': ['str', 'byte', 'bytearray']
}

0 Stimmen

Einige merkwürdige Dinge in diesem Spickzettel: Laut Sammlungen.abc Sequenzen sind Sammlungen, keine Geschwister. Und Iterator unterstützt keine Indizierung, so sollte nicht auf die gleiche Gruppe wie Listen und Tupel sein. Außerdem sind alle text_sequences auch Sequence

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X