collections — Container-Datentypen

Quellcode: Lib/collections/__init__.py


Dieses Modul implementiert spezialisierte Container-Datentypen, die Alternativen zu den allgemeinen integrierten Containern von Python bieten: dict, list, set und tuple.

namedtuple()

Factory-Funktion zum Erstellen von Tupel-Unterklassen mit benannten Feldern

deque

Listenähnlicher Container mit schnellem Anhängen und Entfernen an beiden Enden

ChainMap

Dict-ähnliche Klasse zum Erstellen einer einzelnen Ansicht mehrerer Mappings

Counter

Dict-Unterklasse zum Zählen von hashbaren Objekten

OrderedDict

Dict-Unterklasse, die die Reihenfolge der hinzugefügten Einträge speichert

defaultdict

Dict-Unterklasse, die eine Factory-Funktion aufruft, um fehlende Werte bereitzustellen

UserDict

Wrapper um Dictionary-Objekte für einfacheres Erstellen von Dict-Unterklassen

UserList

Wrapper um Listen-Objekte für einfacheres Erstellen von List-Unterklassen

UserString

Wrapper um String-Objekte für einfacheres Erstellen von String-Unterklassen

ChainMap-Objekte

Hinzugefügt in Version 3.3.

Eine Klasse ChainMap wird bereitgestellt, um eine Reihe von Mappings schnell zu verknüpfen, sodass sie als eine einzige Einheit behandelt werden können. Sie ist oft viel schneller als das Erstellen eines neuen Dictionaries und das Ausführen mehrerer update()-Aufrufe.

Die Klasse kann verwendet werden, um verschachtelte Geltungsbereiche zu simulieren und ist nützlich in Vorlagen.

class collections.ChainMap(*maps)

Eine ChainMap gruppiert mehrere Dictionaries oder andere Mappings, um eine einzelne, aktualisierbare Ansicht zu erstellen. Wenn keine maps angegeben sind, wird ein einzelnes leeres Dictionary bereitgestellt, sodass eine neue Kette immer mindestens ein Mapping enthält.

Die zugrunde liegenden Mappings werden in einer Liste gespeichert. Diese Liste ist öffentlich und kann über das Attribut maps abgerufen oder aktualisiert werden. Es gibt keinen weiteren Zustand.

Lookups durchsuchen die zugrunde liegenden Mappings nacheinander, bis ein Schlüssel gefunden wird. Im Gegensatz dazu wirken sich Schreibvorgänge, Updates und Löschungen nur auf das erste Mapping aus.

Eine ChainMap bindet die zugrunde liegenden Mappings per Referenz ein. Wenn also eines der zugrunde liegenden Mappings aktualisiert wird, spiegeln sich diese Änderungen in der ChainMap wider.

Alle üblichen Dictionary-Methoden werden unterstützt. Zusätzlich gibt es ein maps-Attribut, eine Methode zum Erstellen neuer Unterkontexte und eine Eigenschaft zum Zugriff auf alle bis auf das erste Mapping

maps

Eine vom Benutzer aktualisierbare Liste von Mappings. Die Liste ist vom ersten bis zum letzten durchsuchten Mapping geordnet. Dies ist der einzige gespeicherte Zustand und kann geändert werden, um zu ändern, welche Mappings durchsucht werden. Die Liste sollte immer mindestens ein Mapping enthalten.

new_child(m=None, **kwargs)

Gibt eine neue ChainMap zurück, die ein neues Mapping gefolgt von allen Mappings der aktuellen Instanz enthält. Wenn m angegeben ist, wird es zum neuen Mapping am Anfang der Liste von Mappings; wenn es nicht angegeben ist, wird ein leeres Dictionary verwendet, sodass ein Aufruf von d.new_child() äquivalent ist zu: ChainMap({}, *d.maps). Wenn Schlüsselwortargumente angegeben sind, aktualisieren sie das übergebene Mapping oder ein neues leeres Dictionary. Diese Methode wird zum Erstellen von Unterkontexten verwendet, die aktualisiert werden können, ohne Werte in übergeordneten Mappings zu ändern.

Geändert in Version 3.4: Der optionale Parameter m wurde hinzugefügt.

Geändert in Version 3.10: Die Unterstützung für Schlüsselwortargumente wurde hinzugefügt.

parents

Eine Eigenschaft, die eine neue ChainMap zurückgibt, die alle Mappings der aktuellen Instanz außer dem ersten enthält. Dies ist nützlich, um das erste Mapping in der Suche zu überspringen. Anwendungsfälle sind ähnlich denen des Schlüsselworts nonlocal, das in verschachtelten Geltungsbereichen verwendet wird. Die Anwendungsfälle spiegeln auch die der integrierten Funktion super() wider. Eine Referenz auf d.parents ist äquivalent zu: ChainMap(*d.maps[1:]).

Beachten Sie, dass die Iterationsreihenfolge einer ChainMap durch Scannen der Mappings von hinten nach vorne bestimmt wird

>>> baseline = {'music': 'bach', 'art': 'rembrandt'}
>>> adjustments = {'art': 'van gogh', 'opera': 'carmen'}
>>> list(ChainMap(adjustments, baseline))
['music', 'art', 'opera']

Dies ergibt die gleiche Reihenfolge wie eine Reihe von dict.update()-Aufrufen, beginnend mit dem letzten Mapping

>>> combined = baseline.copy()
>>> combined.update(adjustments)
>>> list(combined)
['music', 'art', 'opera']

Geändert in Version 3.9: Unterstützung für die Operatoren | und |= hinzugefügt, wie in PEP 584 spezifiziert.

Siehe auch

ChainMap Beispiele und Rezepte

Dieser Abschnitt zeigt verschiedene Ansätze für die Arbeit mit verketteten Mappings.

Beispiel zur Simulation der internen Lookup-Kette von Python

import builtins
pylookup = ChainMap(locals(), globals(), vars(builtins))

Beispiel dafür, wie vom Benutzer angegebene Befehlszeilenargumente Vorrang vor Umgebungsvariablen haben, die wiederum Vorrang vor Standardwerten haben

import os, argparse

defaults = {'color': 'red', 'user': 'guest'}

parser = argparse.ArgumentParser()
parser.add_argument('-u', '--user')
parser.add_argument('-c', '--color')
namespace = parser.parse_args()
command_line_args = {k: v for k, v in vars(namespace).items() if v is not None}

combined = ChainMap(command_line_args, os.environ, defaults)
print(combined['color'])
print(combined['user'])

Beispielmuster für die Verwendung der Klasse ChainMap zur Simulation verschachtelter Kontexte

c = ChainMap()        # Create root context
d = c.new_child()     # Create nested child context
e = c.new_child()     # Child of c, independent from d
e.maps[0]             # Current context dictionary -- like Python's locals()
e.maps[-1]            # Root context -- like Python's globals()
e.parents             # Enclosing context chain -- like Python's nonlocals

d['x'] = 1            # Set value in current context
d['x']                # Get first key in the chain of contexts
del d['x']            # Delete from current context
list(d)               # All nested values
k in d                # Check all nested values
len(d)                # Number of nested values
d.items()             # All nested items
dict(d)               # Flatten into a regular dictionary

Die Klasse ChainMap führt Updates (Schreib- und Löschvorgänge) nur für das erste Mapping in der Kette durch, während Lookups die gesamte Kette durchsuchen. Wenn jedoch tiefe Schreib- und Löschvorgänge gewünscht sind, ist es einfach, eine Unterklasse zu erstellen, die Schlüssel aktualisiert, die tiefer in der Kette gefunden werden

class DeepChainMap(ChainMap):
    'Variant of ChainMap that allows direct updates to inner scopes'

    def __setitem__(self, key, value):
        for mapping in self.maps:
            if key in mapping:
                mapping[key] = value
                return
        self.maps[0][key] = value

    def __delitem__(self, key):
        for mapping in self.maps:
            if key in mapping:
                del mapping[key]
                return
        raise KeyError(key)

>>> d = DeepChainMap({'zebra': 'black'}, {'elephant': 'blue'}, {'lion': 'yellow'})
>>> d['lion'] = 'orange'         # update an existing key two levels down
>>> d['snake'] = 'red'           # new keys get added to the topmost dict
>>> del d['elephant']            # remove an existing key one level down
>>> d                            # display result
DeepChainMap({'zebra': 'black', 'snake': 'red'}, {}, {'lion': 'orange'})

Counter-Objekte

Ein Zählwerkzeug wird bereitgestellt, um bequeme und schnelle Zählungen zu unterstützen. Zum Beispiel

>>> # Tally occurrences of words in a list
>>> cnt = Counter()
>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
...     cnt[word] += 1
...
>>> cnt
Counter({'blue': 3, 'red': 2, 'green': 1})

>>> # Find the ten most common words in Hamlet
>>> import re
>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())
>>> Counter(words).most_common(10)
[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),
 ('you', 554),  ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]
class collections.Counter([iterable-oder-mapping])

Ein Counter ist eine dict-Unterklasse zum Zählen von hashbaren Objekten. Es ist eine Sammlung, in der Elemente als Dictionary-Schlüssel gespeichert werden und ihre Zählungen als Dictionary-Werte gespeichert werden. Zählungen dürfen beliebige ganze Zahlen sein, einschließlich Null oder negativer Zählungen. Die Klasse Counter ähnelt Säcken oder Multimengen in anderen Sprachen.

Elemente werden aus einem Iterable gezählt oder aus einem anderen Mapping (oder Counter) initialisiert

>>> c = Counter()                           # a new, empty counter
>>> c = Counter('gallahad')                 # a new counter from an iterable
>>> c = Counter({'red': 4, 'blue': 2})      # a new counter from a mapping
>>> c = Counter(cats=4, dogs=8)             # a new counter from keyword args

Counter-Objekte haben eine Dictionary-Schnittstelle, mit der Ausnahme, dass sie für fehlende Elemente einen Zählwert von Null zurückgeben, anstatt einen KeyError auszulösen

>>> c = Counter(['eggs', 'ham'])
>>> c['bacon']                              # count of a missing element is zero
0

Das Setzen einer Zählung auf Null entfernt kein Element aus einem Counter. Verwenden Sie del, um es vollständig zu entfernen

>>> c['sausage'] = 0                        # counter entry with a zero count
>>> del c['sausage']                        # del actually removes the entry

Hinzugefügt in Version 3.1.

Geändert in Version 3.7: Als dict-Unterklasse erbte Counter die Fähigkeit, die Einfügungsreihenfolge zu speichern. Mathematische Operationen auf Counter-Objekten behalten ebenfalls die Reihenfolge bei. Ergebnisse werden nach der Reihenfolge geordnet, in der ein Element zum ersten Mal im linken Operanden angetroffen wird, und dann nach der Reihenfolge, in der es im rechten Operanden angetroffen wird.

Counter-Objekte unterstützen zusätzliche Methoden über die für alle Dictionaries verfügbaren hinaus

elements()

Gibt einen Iterator über Elemente zurück, der jedes Element so oft wiederholt, wie seine Zählung angibt. Elemente werden in der Reihenfolge der ersten Begegnung zurückgegeben. Wenn die Zählung eines Elements kleiner als eins ist, ignoriert elements() es.

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> sorted(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
most_common([n])

Gibt eine Liste der n häufigsten Elemente und ihrer Zählungen zurück, von der häufigsten bis zur am wenigsten häufigen. Wenn n weggelassen wird oder None ist, gibt most_common() alle Elemente im Counter zurück. Elemente mit gleichen Zählungen werden in der Reihenfolge der ersten Begegnung geordnet

>>> Counter('abracadabra').most_common(3)
[('a', 5), ('b', 2), ('r', 2)]
subtract([iterable-oder-mapping])

Elemente werden von einem Iterable oder von einem anderen Mapping (oder Counter) subtrahiert. Ähnlich wie dict.update(), aber subtrahiert Zählungen anstatt sie zu ersetzen. Sowohl Eingaben als auch Ausgaben können Null oder negativ sein.

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> d = Counter(a=1, b=2, c=3, d=4)
>>> c.subtract(d)
>>> c
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})

Hinzugefügt in Version 3.2.

total()

Berechnet die Summe der Zählungen.

>>> c = Counter(a=10, b=5, c=0)
>>> c.total()
15

Hinzugefügt in Version 3.10.

Die üblichen Dictionary-Methoden sind für Counter-Objekte verfügbar, mit Ausnahme von zwei, die für Counter anders funktionieren.

fromkeys(iterable)

Diese Klassenmethode wird für Counter-Objekte nicht implementiert.

update([iterable-oder-mapping])

Elemente werden aus einem Iterable gezählt oder aus einem anderen Mapping (oder Counter) hinzugefügt. Ähnlich wie dict.update(), aber Zählungen werden addiert anstatt ersetzt. Außerdem wird erwartet, dass das Iterable eine Sequenz von Elementen ist, keine Sequenz von (key, value)-Paaren.

Counter unterstützen Rich-Comparison-Operatoren für Gleichheits-, Teilmengen- und Obermengenbeziehungen: ==, !=, <, <=, >, >=. Alle diese Tests behandeln fehlende Elemente als Zählungen von Null, sodass Counter(a=1) == Counter(a=1, b=0) wahr zurückgibt.

Geändert in Version 3.10: Rich-Comparison-Operationen wurden hinzugefügt.

Geändert in Version 3.10: Bei Gleichheitstests werden fehlende Elemente als Zählungen von Null behandelt. Zuvor wurden Counter(a=3) und Counter(a=3, b=0) als unterschiedlich betrachtet.

Gängige Muster für die Arbeit mit Counter-Objekten

c.total()                       # total of all counts
c.clear()                       # reset all counts
list(c)                         # list unique elements
set(c)                          # convert to a set
dict(c)                         # convert to a regular dictionary
c.items()                       # access the (elem, cnt) pairs
Counter(dict(list_of_pairs))    # convert from a list of (elem, cnt) pairs
c.most_common()[:-n-1:-1]       # n least common elements
+c                              # remove zero and negative counts

Mehrere mathematische Operationen sind für die Kombination von Counter-Objekten vorgesehen, um Multimengen (Counter mit Zählungen größer als Null) zu erzeugen. Addition und Subtraktion kombinieren Counter, indem die Zählungen entsprechender Elemente addiert oder subtrahiert werden. Schnittmenge und Vereinigung geben das Minimum und Maximum der entsprechenden Zählungen zurück. Gleichheit und Inklusion vergleichen entsprechende Zählungen. Jede Operation kann Eingaben mit Vorzeichenzählungen akzeptieren, aber die Ausgabe schließt Ergebnisse mit Zählungen von Null oder weniger aus.

>>> c = Counter(a=3, b=1)
>>> d = Counter(a=1, b=2)
>>> c + d                       # add two counters together:  c[x] + d[x]
Counter({'a': 4, 'b': 3})
>>> c - d                       # subtract (keeping only positive counts)
Counter({'a': 2})
>>> c & d                       # intersection:  min(c[x], d[x])
Counter({'a': 1, 'b': 1})
>>> c | d                       # union:  max(c[x], d[x])
Counter({'a': 3, 'b': 2})
>>> c == d                      # equality:  c[x] == d[x]
False
>>> c <= d                      # inclusion:  c[x] <= d[x]
False

Unäre Addition und Subtraktion sind Abkürzungen für die Addition eines leeren Counters oder die Subtraktion von einem leeren Counter.

>>> c = Counter(a=2, b=-4)
>>> +c
Counter({'a': 2})
>>> -c
Counter({'b': 4})

Hinzugefügt in Version 3.3: Unterstützung für unäre Plus-, unäre Minus- und In-Place-Multimengenoperationen hinzugefügt.

Hinweis

Counter wurden hauptsächlich für die Arbeit mit positiven Ganzzahlen zur Darstellung laufender Zählungen entwickelt; es wurde jedoch darauf geachtet, Anwendungsfälle mit anderen Typen oder negativen Werten nicht unnötig auszuschließen. Um bei diesen Anwendungsfällen zu helfen, dokumentiert dieser Abschnitt die minimalen Bereichs- und Typbeschränkungen.

  • Die Klasse Counter selbst ist eine Dictionary-Unterklasse ohne Einschränkungen für ihre Schlüssel und Werte. Die Werte sind als Zahlen gedacht, die Zählungen darstellen, aber Sie *könnten* alles im Wertfeld speichern.

  • Die Methode most_common() erfordert nur, dass die Werte sortierbar sind.

  • Für In-Place-Operationen wie c[key] += 1 muss der Werttyp nur Addition und Subtraktion unterstützen. Daher wären Brüche, Gleitkommazahlen und Dezimalzahlen möglich und negative Werte werden unterstützt. Das Gleiche gilt auch für update() und subtract(), die negative und Nullwerte sowohl für Eingaben als auch für Ausgaben zulassen.

  • Die Multimengen-Methoden sind nur für Anwendungsfälle mit positiven Werten konzipiert. Die Eingaben können negativ oder Null sein, aber es werden nur Ausgaben mit positiven Werten erzeugt. Es gibt keine Typbeschränkungen, aber der Werttyp muss Addition, Subtraktion und Vergleich unterstützen.

  • Die Methode elements() erfordert ganzzahlige Zählungen. Sie ignoriert Null- und Negativzählungen.

Siehe auch

  • Bag-Klasse in Smalltalk.

  • Wikipedia-Eintrag für Multisets.

  • C++ Multisets Tutorial mit Beispielen.

  • Für mathematische Operationen auf Multimengen und deren Anwendungsfälle siehe Knuth, Donald. The Art of Computer Programming Band II, Abschnitt 4.6.3, Übung 19.

  • Um alle verschiedenen Multimengen einer bestimmten Größe über einer gegebenen Menge von Elementen aufzulisten, siehe itertools.combinations_with_replacement()

    map(Counter, combinations_with_replacement('ABC', 2)) # --> AA AB AC BB BC CC
    

deque-Objekte

class collections.deque([iterable[, maxlen]])

Gibt ein neues Deque-Objekt zurück, das von links nach rechts initialisiert wurde (mit append()) mit Daten aus iterable. Wenn iterable nicht angegeben ist, ist das neue Deque leer.

Deques sind eine Verallgemeinerung von Stacks und Queues (der Name wird „Deck“ ausgesprochen und ist eine Kurzform für „double-ended queue“). Deques unterstützen thread-sichere, speichereffiziente Anhänge- und Entnahmevorgänge von beiden Seiten des Deques mit ungefähr der gleichen O(1)-Performance in beide Richtungen.

Obwohl list-Objekte ähnliche Operationen unterstützen, sind sie für schnelle Operationen mit fester Länge optimiert und verursachen O(n) Kosten für die Speicherbewegung bei pop(0) und insert(0, v)-Operationen, die sowohl die Größe als auch die Position der zugrunde liegenden Datenrepräsentation ändern.

Wenn maxlen nicht angegeben ist oder None ist, können sich Deques beliebig lang ausdehnen. Andernfalls ist das Deque auf die angegebene maximale Länge beschränkt. Sobald ein Deque mit begrenzter Länge voll ist, werden beim Hinzufügen neuer Elemente eine entsprechende Anzahl von Elementen vom gegenüberliegenden Ende verworfen. Deques mit begrenzter Länge bieten Funktionalität ähnlich dem tail-Filter in Unix. Sie sind auch nützlich für die Verfolgung von Transaktionen und anderen Datenpools, bei denen nur die aktuellste Aktivität von Interesse ist.

Deque-Objekte unterstützen die folgenden Methoden

append(x)

Fügt x an die rechte Seite des Deques an.

appendleft(x)

Fügt x an die linke Seite des Deques an.

clear()

Entfernt alle Elemente aus dem Deque, wodurch es die Länge 0 hat.

copy()

Erstellt eine flache Kopie des Deques.

Hinzugefügt in Version 3.5.

count(x)

Zählt die Anzahl der Elemente im Deque, die gleich x sind.

Hinzugefügt in Version 3.2.

extend(iterable)

Erweitert die rechte Seite des Deques, indem Elemente aus dem Iterable-Argument angehängt werden.

extendleft(iterable)

Erweitert die linke Seite des Deques, indem Elemente aus iterable angehängt werden. Beachten Sie, dass die Serie von linken Anhängen die Reihenfolge der Elemente im Iterable-Argument umkehrt.

index(x[, start[, stop]])

Gibt die Position von x im Deque zurück (ab Index start und vor Index stop). Gibt die erste Übereinstimmung zurück oder löst einen ValueError aus, wenn nicht gefunden.

Hinzugefügt in Version 3.5.

insert(i, x)

Fügt x im Deque an Position i ein.

Wenn die Einfügung dazu führt, dass ein begrenztes Deque die maxlen überschreitet, wird ein IndexError ausgelöst.

Hinzugefügt in Version 3.5.

pop()

Entfernt und gibt ein Element von der rechten Seite des Deques zurück. Wenn keine Elemente vorhanden sind, wird ein IndexError ausgelöst.

popleft()

Entfernt und gibt ein Element von der linken Seite des Deques zurück. Wenn keine Elemente vorhanden sind, wird ein IndexError ausgelöst.

remove(value)

Entfernt die erste Vorkommnis von value. Wenn nicht gefunden, wird ein ValueError ausgelöst.

reverse()

Kehrt die Elemente des Deques an Ort und Stelle um und gibt dann None zurück.

Hinzugefügt in Version 3.2.

rotate(n=1)

Rotiert das Deque um n Schritte nach rechts. Wenn n negativ ist, rotiert es nach links.

Wenn das Deque nicht leer ist, ist eine Drehung um einen Schritt nach rechts äquivalent zu d.appendleft(d.pop()), und eine Drehung um einen Schritt nach links ist äquivalent zu d.append(d.popleft()).

Deque-Objekte bieten auch ein schreibgeschütztes Attribut

maxlen

Maximale Größe eines Deques oder None, wenn unbeschränkt.

Hinzugefügt in Version 3.1.

Zusätzlich zu den oben genannten unterstützt das Deque Iteration, Pickling, len(d), reversed(d), copy.copy(d), copy.deepcopy(d), Mitgliedschaftstests mit dem Operator in und Subskript-Referenzen wie d[0] für den Zugriff auf das erste Element. Der indizierte Zugriff ist an beiden Enden O(1), verlangsamt sich aber in der Mitte auf O(n). Für schnellen zufälligen Zugriff verwenden Sie stattdessen Listen.

Ab Version 3.5 unterstützt das Deque __add__(), __mul__() und __imul__().

Beispiel

>>> from collections import deque
>>> d = deque('ghi')                 # make a new deque with three items
>>> for elem in d:                   # iterate over the deque's elements
...     print(elem.upper())
G
H
I

>>> d.append('j')                    # add a new entry to the right side
>>> d.appendleft('f')                # add a new entry to the left side
>>> d                                # show the representation of the deque
deque(['f', 'g', 'h', 'i', 'j'])

>>> d.pop()                          # return and remove the rightmost item
'j'
>>> d.popleft()                      # return and remove the leftmost item
'f'
>>> list(d)                          # list the contents of the deque
['g', 'h', 'i']
>>> d[0]                             # peek at leftmost item
'g'
>>> d[-1]                            # peek at rightmost item
'i'

>>> list(reversed(d))                # list the contents of a deque in reverse
['i', 'h', 'g']
>>> 'h' in d                         # search the deque
True
>>> d.extend('jkl')                  # add multiple elements at once
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> d.rotate(1)                      # right rotation
>>> d
deque(['l', 'g', 'h', 'i', 'j', 'k'])
>>> d.rotate(-1)                     # left rotation
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])

>>> deque(reversed(d))               # make a new deque in reverse order
deque(['l', 'k', 'j', 'i', 'h', 'g'])
>>> d.clear()                        # empty the deque
>>> d.pop()                          # cannot pop from an empty deque
Traceback (most recent call last):
    File "<pyshell#6>", line 1, in -toplevel-
        d.pop()
IndexError: pop from an empty deque

>>> d.extendleft('abc')              # extendleft() reverses the input order
>>> d
deque(['c', 'b', 'a'])

deque Rezepte

Dieser Abschnitt zeigt verschiedene Ansätze für die Arbeit mit Deques.

Deques mit begrenzter Länge bieten Funktionalität, die dem tail-Filter in Unix ähnelt

def tail(filename, n=10):
    'Return the last n lines of a file'
    with open(filename) as f:
        return deque(f, n)

Ein weiterer Ansatz zur Verwendung von Deques ist die Aufrechterhaltung einer Sequenz von kürzlich hinzugefügten Elementen, indem man an die rechte Seite anhängt und von der linken Seite entfernt

def moving_average(iterable, n=3):
    # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0
    # https://en.wikipedia.org/wiki/Moving_average
    it = iter(iterable)
    d = deque(itertools.islice(it, n-1))
    d.appendleft(0)
    s = sum(d)
    for elem in it:
        s += elem - d.popleft()
        d.append(elem)
        yield s / n

Ein Round-Robin-Scheduler kann mit Eingabeiteratoren implementiert werden, die in einem deque gespeichert sind. Werte werden vom aktiven Iterator an Position Null ausgegeben. Wenn dieser Iterator erschöpft ist, kann er mit popleft() entfernt werden; andernfalls kann er mit der Methode rotate() zurück ans Ende geschleift werden

def roundrobin(*iterables):
    "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
    iterators = deque(map(iter, iterables))
    while iterators:
        try:
            while True:
                yield next(iterators[0])
                iterators.rotate(-1)
        except StopIteration:
            # Remove an exhausted iterator.
            iterators.popleft()

Die Methode rotate() bietet eine Möglichkeit, deque-Slicing und -Löschung zu implementieren. Zum Beispiel stützt sich eine reine Python-Implementierung von del d[n] auf die Methode rotate(), um die zu entfernenden Elemente an die linke Seite des Deques zu positionieren

def delete_nth(d, n):
    d.rotate(-n)
    d.popleft()
    d.rotate(n)

Um deque-Slicing zu implementieren, verwenden Sie einen ähnlichen Ansatz, indem Sie rotate() anwenden, um ein Ziel-Element an die linke Seite des Deques zu bringen. Entfernen Sie alte Einträge mit popleft(), fügen Sie neue Einträge mit extend() hinzu und kehren Sie dann die Rotation um. Mit geringfügigen Variationen dieses Ansatzes ist es einfach, Forth-artige Stapelmanipulationen wie dup, drop, swap, over, pick, rot und roll zu implementieren.

defaultdict-Objekte

class collections.defaultdict(default_factory=None, /[, ...])

Gibt ein neues dictionary-ähnliches Objekt zurück. defaultdict ist eine Unterklasse der eingebauten dict-Klasse. Sie überschreibt eine Methode und fügt eine beschreibbare Instanzvariable hinzu. Die restliche Funktionalität ist die gleiche wie bei der dict-Klasse und wird hier nicht dokumentiert.

Das erste Argument liefert den Anfangswert für das Attribut default_factory; es ist standardmäßig None. Alle restlichen Argumente werden so behandelt, als wären sie dem Konstruktor von dict übergeben worden, einschließlich Schlüsselwortargumenten.

defaultdict-Objekte unterstützen zusätzlich zu den Standardoperationen von dict die folgende Methode

__missing__(key)

Wenn das Attribut default_factory None ist, wird eine KeyError-Ausnahme mit dem key als Argument ausgelöst.

Wenn default_factory nicht None ist, wird es ohne Argumente aufgerufen, um einen Standardwert für den gegebenen key bereitzustellen. Dieser Wert wird im Dictionary für den key eingefügt und zurückgegeben.

Wenn der Aufruf von default_factory eine Ausnahme auslöst, wird diese Ausnahme unverändert weitergegeben.

Diese Methode wird von der __getitem__()-Methode der dict-Klasse aufgerufen, wenn der angeforderte Schlüssel nicht gefunden wird. Was auch immer sie zurückgibt oder auslöst, wird dann von __getitem__() zurückgegeben oder ausgelöst.

Beachten Sie, dass __missing__() für andere Operationen als __getitem__() *nicht* aufgerufen wird. Das bedeutet, dass get(), wie normale Dictionaries, None als Standard zurückgibt, anstatt default_factory zu verwenden.

defaultdict-Objekte unterstützen die folgende Instanzvariable

default_factory

Dieses Attribut wird von der Methode __missing__() verwendet; es wird aus dem ersten Argument des Konstruktors initialisiert, falls vorhanden, oder auf None, falls abwesend.

Geändert in Version 3.9: Hinzugefügt wurden die Operatoren für Zusammenführung (|) und Aktualisierung (|=), spezifiziert in PEP 584.

defaultdict Beispiele

Wenn list als default_factory verwendet wird, ist es einfach, eine Sequenz von Schlüssel-Wert-Paaren in einem Dictionary von Listen zu gruppieren

>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
...     d[k].append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

Wenn ein Schlüssel zum ersten Mal angetroffen wird, ist er noch nicht im Mapping vorhanden; daher wird automatisch ein Eintrag erstellt, der die default_factory-Funktion verwendet, die eine leere list zurückgibt. Der Vorgang list.append() fügt dann den Wert zur neuen Liste hinzu. Wenn Schlüssel erneut angetroffen werden, läuft die Suche normal ab (gibt die Liste für diesen Schlüssel zurück) und der Vorgang list.append() fügt einen weiteren Wert zur Liste hinzu. Diese Technik ist einfacher und schneller als eine äquivalente Technik mit dict.setdefault()

>>> d = {}
>>> for k, v in s:
...     d.setdefault(k, []).append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

Durch Setzen des default_factory auf int wird der defaultdict nützlich für das Zählen (wie ein Beutel oder Multiset in anderen Sprachen)

>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
...     d[k] += 1
...
>>> sorted(d.items())
[('i', 4), ('m', 1), ('p', 2), ('s', 4)]

Wenn ein Buchstabe zum ersten Mal angetroffen wird, fehlt er im Mapping, daher ruft die default_factory-Funktion int() auf, um einen Standardzähler von Null bereitzustellen. Der Inkrementvorgang baut dann den Zähler für jeden Buchstaben auf.

Die Funktion int(), die immer Null zurückgibt, ist nur ein Sonderfall von konstanten Funktionen. Eine schnellere und flexiblere Methode, konstante Funktionen zu erstellen, ist die Verwendung einer Lambda-Funktion, die jeden beliebigen konstanten Wert (nicht nur Null) bereitstellen kann

>>> def constant_factory(value):
...     return lambda: value
...
>>> d = defaultdict(constant_factory('<missing>'))
>>> d.update(name='John', action='ran')
>>> '%(name)s %(action)s to %(object)s' % d
'John ran to <missing>'

Durch Setzen des default_factory auf set wird der defaultdict nützlich zum Erstellen eines Dictionaries von Sets

>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
>>> d = defaultdict(set)
>>> for k, v in s:
...     d[k].add(v)
...
>>> sorted(d.items())
[('blue', {2, 4}), ('red', {1, 3})]

namedtuple() Fabrikfunktion für Tupel mit benannten Feldern

Benannte Tupel weisen jeder Position in einem Tupel eine Bedeutung zu und ermöglichen lesbareren, selbsterklärenden Code. Sie können überall dort verwendet werden, wo normale Tupel verwendet werden, und sie fügen die Möglichkeit hinzu, auf Felder über Attributzugriff zuzugreifen, anstatt nur über Index. Instanzen der Unterklasse haben auch eine hilfreiche Docstring (mit typename und field_names) und eine hilfreiche __repr__()-Methode, die die Tupelinhalte im Format name=value auflistet.

collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)

Gibt eine neue Tupel-Unterklasse mit dem Namen typename zurück. Die neue Unterklasse wird verwendet, um tupelähnliche Objekte zu erstellen, deren Felder per Attributzugriff erreichbar sind und die auch indizierbar und iterierbar sind. Instanzen der Unterklasse haben auch einen hilfreichen Docstring (mit typename und field_names) und eine hilfreiche __repr__()-Methode, die die Tupelinhalte im Format name=value auflistet.

Die field_names sind eine Sequenz von Zeichenketten wie z. B. ['x', 'y']. Alternativ können field_names eine einzelne Zeichenkette sein, bei der jedes Feld durch Leerzeichen und/oder Kommas getrennt ist, z. B. 'x y' oder 'x, y'.

Jeder gültige Python-Bezeichner kann für einen Feldnamen verwendet werden, außer für Namen, die mit einem Unterstrich beginnen. Gültige Bezeichner bestehen aus Buchstaben, Ziffern und Unterstrichen, beginnen jedoch nicht mit einer Ziffer oder einem Unterstrich und dürfen kein Schlüsselwort wie class, for, return, global, pass oder raise sein.

Wenn rename true ist, werden ungültige Feldnamen automatisch durch Positionsnamen ersetzt. Zum Beispiel wird ['abc', 'def', 'ghi', 'abc'] in ['abc', '_1', 'ghi', '_3'] umgewandelt, wobei das Schlüsselwort def und der doppelte Feldname abc eliminiert werden.

defaults kann None oder ein Iterable von Standardwerten sein. Da Felder mit einem Standardwert nach allen Feldern ohne Standardwert kommen müssen, werden die defaults auf die rechtesten Parameter angewendet. Wenn die Feldnamen beispielsweise ['x', 'y', 'z'] und die Standardwerte (1, 2) sind, dann ist x ein erforderliches Argument, y hat standardmäßig 1 und z hat standardmäßig 2.

Wenn module definiert ist, wird das Attribut __module__ des benannten Tupels auf diesen Wert gesetzt.

Instanzen benannter Tupel haben keine Instanz-Dictionaries, daher sind sie leichtgewichtig und benötigen nicht mehr Speicher als normale Tupel.

Zur Unterstützung des Pickling sollte die Klasse des benannten Tupels einer Variablen zugewiesen werden, die typename entspricht.

Geändert in Version 3.1: Unterstützung für rename hinzugefügt.

Geändert in Version 3.6: Die Parameter verbose und rename wurden zu Schlüsselwort-Only-Argumenten.

Geändert in Version 3.6: Der Parameter module hinzugefügt.

Geändert in Version 3.7: Der Parameter verbose und das Attribut _source entfernt.

Geändert in Version 3.7: Der Parameter defaults und das Attribut _field_defaults hinzugefügt.

>>> # Basic example
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(11, y=22)     # instantiate with positional or keyword arguments
>>> p[0] + p[1]             # indexable like the plain tuple (11, 22)
33
>>> x, y = p                # unpack like a regular tuple
>>> x, y
(11, 22)
>>> p.x + p.y               # fields also accessible by name
33
>>> p                       # readable __repr__ with a name=value style
Point(x=11, y=22)

Benannte Tupel sind besonders nützlich, um Feldnamen Ergebnis-Tupeln zuzuweisen, die von den Modulen csv oder sqlite3 zurückgegeben werden

EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')

import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
    print(emp.name, emp.title)

import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):
    print(emp.name, emp.title)

Zusätzlich zu den von Tupeln geerbten Methoden unterstützen benannte Tupel drei zusätzliche Methoden und zwei Attribute. Um Konflikte mit Feldnamen zu vermeiden, beginnen die Methoden- und Attributnamen mit einem Unterstrich.

classmethod somenamedtuple._make(iterable)

Klassenmethode, die eine neue Instanz aus einer vorhandenen Sequenz oder einem Iterable erstellt.

>>> t = [11, 22]
>>> Point._make(t)
Point(x=11, y=22)
somenamedtuple._asdict()

Gibt ein neues dict zurück, das Feldnamen ihren entsprechenden Werten zuordnet

>>> p = Point(x=11, y=22)
>>> p._asdict()
{'x': 11, 'y': 22}

Geändert in Version 3.1: Gibt ein OrderedDict anstelle eines regulären dict zurück.

Geändert in Version 3.8: Gibt ein reguläres dict anstelle eines OrderedDict zurück. Ab Python 3.7 sind reguläre Dictionaries garantiert geordnet. Wenn die zusätzlichen Funktionen von OrderedDict benötigt werden, ist die empfohlene Abhilfe, das Ergebnis in den gewünschten Typ zu casten: OrderedDict(nt._asdict()).

somenamedtuple._replace(**kwargs)

Gibt eine neue Instanz des benannten Tupels zurück, bei der angegebene Felder durch neue Werte ersetzt werden

>>> p = Point(x=11, y=22)
>>> p._replace(x=33)
Point(x=33, y=22)

>>> for partnum, record in inventory.items():
...     inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())

Benannte Tupel werden auch von der generischen Funktion copy.replace() unterstützt.

Geändert in Version 3.13: Löst stattdessen TypeError anstelle von ValueError für ungültige Schlüsselwortargumente aus.

somenamedtuple._fields

Tupel von Zeichenketten, die die Feldnamen auflisten. Nützlich für Introspektion und zur Erstellung neuer benannter Tupeltypen aus vorhandenen benannten Tupeln.

>>> p._fields            # view the field names
('x', 'y')

>>> Color = namedtuple('Color', 'red green blue')
>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)
>>> Pixel(11, 22, 128, 255, 0)
Pixel(x=11, y=22, red=128, green=255, blue=0)
somenamedtuple._field_defaults

Dictionary, das Feldnamen auf Standardwerte abbildet.

>>> Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
>>> Account._field_defaults
{'balance': 0}
>>> Account('premium')
Account(type='premium', balance=0)

Um ein Feld abzurufen, dessen Name in einer Zeichenkette gespeichert ist, verwenden Sie die Funktion getattr()

>>> getattr(p, 'x')
11

Um ein Dictionary in ein benanntes Tupel zu konvertieren, verwenden Sie den Doppelstern-Operator (wie in Entpacken von Argumentlisten beschrieben)

>>> d = {'x': 11, 'y': 22}
>>> Point(**d)
Point(x=11, y=22)

Da ein benanntes Tupel eine reguläre Python-Klasse ist, ist es einfach, Funktionalität mit einer Unterklasse hinzuzufügen oder zu ändern. Hier ist, wie ein berechnetes Feld und ein festes Druckformat hinzugefügt werden können

>>> class Point(namedtuple('Point', ['x', 'y'])):
...     __slots__ = ()
...     @property
...     def hypot(self):
...         return (self.x ** 2 + self.y ** 2) ** 0.5
...     def __str__(self):
...         return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

>>> for p in Point(3, 4), Point(14, 5/7):
...     print(p)
Point: x= 3.000  y= 4.000  hypot= 5.000
Point: x=14.000  y= 0.714  hypot=14.018

Die oben gezeigte Unterklasse setzt __slots__ auf ein leeres Tupel. Dies hilft, den Speicherbedarf gering zu halten, indem die Erstellung von Instanz-Dictionaries verhindert wird.

Unterklassenbildung ist nicht nützlich, um neue, gespeicherte Felder hinzuzufügen. Erstellen Sie stattdessen einfach einen neuen benannten Tupeltyp aus dem Attribut _fields

>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))

Docstrings können angepasst werden, indem direkte Zuweisungen an die __doc__ Felder vorgenommen werden

>>> Book = namedtuple('Book', ['id', 'title', 'authors'])
>>> Book.__doc__ += ': Hardcover book in active collection'
>>> Book.id.__doc__ = '13-digit ISBN'
>>> Book.title.__doc__ = 'Title of first printing'
>>> Book.authors.__doc__ = 'List of authors sorted by last name'

Geändert in Version 3.5: Property-Docstrings wurden beschreibbar.

Siehe auch

  • Siehe typing.NamedTuple für eine Möglichkeit, Typ-Hints für benannte Tupel hinzuzufügen. Es bietet auch eine elegante Notation mit dem Schlüsselwort class

    class Component(NamedTuple):
        part_number: int
        weight: float
        description: Optional[str] = None
    
  • Siehe types.SimpleNamespace() für einen veränderlichen Namespace, der auf einem zugrundeliegenden Dictionary anstelle eines Tupels basiert.

  • Das Modul dataclasses bietet einen Dekorator und Funktionen zum automatischen Hinzufügen von generierten Spezialmethoden zu benutzerdefinierten Klassen.

OrderedDict Objekte

Geordnete Dictionaries sind wie reguläre Dictionaries, haben aber einige zusätzliche Fähigkeiten in Bezug auf Ordnungsvorgänge. Sie sind weniger wichtig geworden, da die eingebaute dict-Klasse die Fähigkeit erhalten hat, die Einfügungsreihenfolge zu merken (dieses neue Verhalten wurde in Python 3.7 garantiert).

Einige Unterschiede zu dict bestehen weiterhin

  • Das reguläre dict wurde entwickelt, um sehr gut für Mapping-Operationen geeignet zu sein. Das Verfolgen der Einfügungsreihenfolge war sekundär.

  • Das OrderedDict wurde entwickelt, um gut für Umordnungsoperationen geeignet zu sein. Speichereffizienz, Iterationsgeschwindigkeit und die Leistung von Update-Operationen waren sekundär.

  • Der Algorithmus von OrderedDict kann häufige Umordnungsoperationen besser handhaben als dict. Wie in den folgenden Rezepten gezeigt, eignet es sich daher zur Implementierung verschiedener Arten von LRU-Caches.

  • Der Gleichheitstest für OrderedDict prüft auf übereinstimmende Reihenfolge.

    Ein reguläres dict kann den reihenfolgesensitiven Gleichheitstest mit p == q and all(k1 == k2 for k1, k2 in zip(p, q)) emulieren.

  • Die Methode popitem() von OrderedDict hat eine andere Signatur. Sie akzeptiert ein optionales Argument zur Angabe, welches Element entfernt wird.

    Ein reguläres dict kann OrderedDicts od.popitem(last=True) mit d.popitem() emulieren, was garantiert das rechteste (letzte) Element entfernt.

    Ein reguläres dict kann OrderedDicts od.popitem(last=False) mit (k := next(iter(d)), d.pop(k)) emulieren, was das linkeste (erste) Element zurückgibt und entfernt, falls es existiert.

  • OrderedDict hat eine Methode move_to_end(), um ein Element effizient zu einem Endpunkt zu verschieben.

    Ein reguläres dict kann OrderedDicts d[k] = d.pop(k) emulieren, was den Schlüssel und seinen zugehörigen Wert an die rechteste (letzte) Position verschiebt.

    Ein reguläres dict hat kein effizientes Äquivalent für OrderedDicts od.move_to_end(k, last=False), was den Schlüssel und seinen zugehörigen Wert an die linkeste (erste) Position verschiebt.

  • Bis Python 3.8 fehlte dict eine __reversed__()-Methode.

class collections.OrderedDict([items])

Gibt eine Instanz einer dict-Unterklasse zurück, die über spezialisierte Methoden zur Neuanordnung der Dictionary-Reihenfolge verfügt.

Hinzugefügt in Version 3.1.

popitem(last=True)

Die Methode popitem() für geordnete Dictionaries gibt ein (Schlüssel, Wert)-Paar zurück und entfernt es. Die Paare werden in LIFO-Reihenfolge zurückgegeben, wenn last true ist, oder in FIFO-Reihenfolge, wenn false.

move_to_end(key, last=True)

Verschiebt einen vorhandenen key an ein Ende eines geordneten Dictionaries. Das Element wird an das rechte Ende verschoben, wenn last true ist (Standard), oder an den Anfang, wenn last false ist. Löst KeyError aus, wenn der key nicht existiert.

>>> d = OrderedDict.fromkeys('abcde')
>>> d.move_to_end('b')
>>> ''.join(d)
'acdeb'
>>> d.move_to_end('b', last=False)
>>> ''.join(d)
'bacde'

Hinzugefügt in Version 3.2.

Zusätzlich zu den üblichen Mapping-Methoden unterstützen geordnete Dictionaries auch die umgekehrte Iteration mit reversed().

Gleichheitstests zwischen OrderedDict-Objekten sind reihenfolgesensitiv und entsprechen grob list(od1.items())==list(od2.items()).

Gleichheitstests zwischen OrderedDict-Objekten und anderen Mapping-Objekten sind reihenfolgenunempfindlich wie reguläre Dictionaries. Dies ermöglicht, dass OrderedDict-Objekte überall dort eingesetzt werden können, wo ein reguläres Dictionary verwendet wird.

Geändert in Version 3.5: Die Views für Elemente, Schlüssel und Werte von OrderedDict unterstützen nun die umgekehrte Iteration mit reversed().

Geändert in Version 3.6: Mit der Akzeptanz von PEP 468 wird die Reihenfolge für Schlüsselwortargumente beibehalten, die dem Konstruktor von OrderedDict und seiner Methode update() übergeben werden.

Geändert in Version 3.9: Hinzugefügt wurden die Operatoren für Zusammenführung (|) und Aktualisierung (|=), spezifiziert in PEP 584.

OrderedDict Beispiele und Rezepte

Es ist einfach, eine geordnete Wörterbuchvariante zu erstellen, die die Reihenfolge der zuletzt eingefügten Schlüssel beibehält. Wenn ein neuer Eintrag einen vorhandenen Eintrag überschreibt, wird die ursprüngliche Einfügeposition geändert und ans Ende verschoben.

class LastUpdatedOrderedDict(OrderedDict):
    'Store items in the order the keys were last added'

    def __setitem__(self, key, value):
        super().__setitem__(key, value)
        self.move_to_end(key)

Ein OrderedDict wäre auch nützlich für die Implementierung von Varianten von functools.lru_cache().

from collections import OrderedDict
from time import time

class TimeBoundedLRU:
    "LRU Cache that invalidates and refreshes old entries."

    def __init__(self, func, maxsize=128, maxage=30):
        self.cache = OrderedDict()      # { args : (timestamp, result)}
        self.func = func
        self.maxsize = maxsize
        self.maxage = maxage

    def __call__(self, *args):
        if args in self.cache:
            self.cache.move_to_end(args)
            timestamp, result = self.cache[args]
            if time() - timestamp <= self.maxage:
                return result
        result = self.func(*args)
        self.cache[args] = time(), result
        if len(self.cache) > self.maxsize:
            self.cache.popitem(last=False)
        return result
class MultiHitLRUCache:
    """ LRU cache that defers caching a result until
        it has been requested multiple times.

        To avoid flushing the LRU cache with one-time requests,
        we don't cache until a request has been made more than once.

    """

    def __init__(self, func, maxsize=128, maxrequests=4096, cache_after=1):
        self.requests = OrderedDict()   # { uncached_key : request_count }
        self.cache = OrderedDict()      # { cached_key : function_result }
        self.func = func
        self.maxrequests = maxrequests  # max number of uncached requests
        self.maxsize = maxsize          # max number of stored return values
        self.cache_after = cache_after

    def __call__(self, *args):
        if args in self.cache:
            self.cache.move_to_end(args)
            return self.cache[args]
        result = self.func(*args)
        self.requests[args] = self.requests.get(args, 0) + 1
        if self.requests[args] <= self.cache_after:
            self.requests.move_to_end(args)
            if len(self.requests) > self.maxrequests:
                self.requests.popitem(last=False)
        else:
            self.requests.pop(args, None)
            self.cache[args] = result
            if len(self.cache) > self.maxsize:
                self.cache.popitem(last=False)
        return result

UserDict-Objekte

Die Klasse UserDict fungiert als Wrapper um Wörterbuchobjekte. Die Notwendigkeit dieser Klasse wurde teilweise durch die Möglichkeit, direkt von dict zu erben, ersetzt. Diese Klasse kann jedoch einfacher zu handhaben sein, da das zugrunde liegende Wörterbuch als Attribut zugänglich ist.

class collections.UserDict([initialdata])

Klasse, die ein Wörterbuch simuliert. Der Inhalt der Instanz wird in einem regulären Wörterbuch gespeichert, das über das Attribut data von UserDict-Instanzen zugänglich ist. Wenn initialdata bereitgestellt wird, wird data mit dessen Inhalt initialisiert; Beachten Sie, dass keine Referenz auf initialdata gespeichert wird, sodass es für andere Zwecke verwendet werden kann.

Zusätzlich zur Unterstützung der Methoden und Operationen von Abbildungen stellen UserDict-Instanzen das folgende Attribut bereit:

data

Ein echtes Wörterbuch, das zum Speichern des Inhalts der UserDict-Klasse verwendet wird.

UserList-Objekte

Diese Klasse fungiert als Wrapper um Listenobjekte. Sie ist eine nützliche Basisklasse für Ihre eigenen Listen-ähnlichen Klassen, von denen Sie erben und vorhandene Methoden überschreiben oder neue hinzufügen können. Auf diese Weise kann Listen neues Verhalten hinzugefügt werden.

Die Notwendigkeit dieser Klasse wurde teilweise durch die Möglichkeit, direkt von list zu erben, ersetzt. Diese Klasse kann jedoch einfacher zu handhaben sein, da die zugrunde liegende Liste als Attribut zugänglich ist.

class collections.UserList([list])

Klasse, die eine Liste simuliert. Der Inhalt der Instanz wird in einer regulären Liste gespeichert, die über das Attribut data von UserList-Instanzen zugänglich ist. Der Inhalt der Instanz wird zunächst als Kopie von list initialisiert, wobei standardmäßig die leere Liste [] verwendet wird. list kann ein beliebiges iterierbares Objekt sein, z. B. eine echte Python-Liste oder ein UserList-Objekt.

Zusätzlich zur Unterstützung der Methoden und Operationen von veränderlichen Sequenzen stellen UserList-Instanzen das folgende Attribut bereit:

data

Ein echtes list-Objekt, das zum Speichern des Inhalts der UserList-Klasse verwendet wird.

Anforderungen für Unterklassen: Unterklassen von UserList müssen einen Konstruktor anbieten, der entweder ohne Argumente oder mit einem Argument aufgerufen werden kann. Listenoperationen, die eine neue Sequenz zurückgeben, versuchen, eine Instanz der tatsächlichen Implementierungsklasse zu erstellen. Dazu wird davon ausgegangen, dass der Konstruktor mit einem einzelnen Parameter aufgerufen werden kann, bei dem es sich um ein Sequenzobjekt handelt, das als Datenquelle dient.

Wenn eine abgeleitete Klasse dieser Anforderung nicht nachkommen möchte, müssen alle von dieser Klasse unterstützten Sonder-Methoden überschrieben werden. Bitte konsultieren Sie die Quellcodes für Informationen über die Methoden, die in diesem Fall bereitgestellt werden müssen.

UserString-Objekte

Die Klasse UserString fungiert als Wrapper um Zeichenkettenobjekte. Die Notwendigkeit dieser Klasse wurde teilweise durch die Möglichkeit, direkt von str zu erben, ersetzt. Diese Klasse kann jedoch einfacher zu handhaben sein, da die zugrunde liegende Zeichenkette als Attribut zugänglich ist.

class collections.UserString(seq)

Klasse, die ein Zeichenkettenobjekt simuliert. Der Inhalt der Instanz wird in einem regulären Zeichenkettenobjekt gespeichert, das über das Attribut data von UserString-Instanzen zugänglich ist. Der Inhalt der Instanz wird zunächst als Kopie von seq initialisiert. Das Argument seq kann jedes Objekt sein, das mit der integrierten Funktion str() in eine Zeichenkette umgewandelt werden kann.

Zusätzlich zur Unterstützung der Methoden und Operationen von Zeichenketten stellen UserString-Instanzen das folgende Attribut bereit:

data

Ein echtes str-Objekt, das zum Speichern des Inhalts der UserString-Klasse verwendet wird.

Geändert in Version 3.5: Neue Methoden __getnewargs__, __rmod__, casefold, format_map, isprintable und maketrans.