Das collections-Modul in Python: Counter, defaultdict und mehr

Pythons collections-Modul bietet spezialisierte Datentypen, die dir viel Boilerplate ersparen. Lerne Counter, defaultdict, namedtuple und deque kennen – mit praktischen Beispielen.

Teilen

Die eingebauten Datentypen list, dict und tuple begleiten dich in Python von Anfang an. Doch für viele wiederkehrende Aufgaben gibt es elegantere Werkzeuge: das collections-Modul aus der Standardbibliothek. Es liefert dir spezialisierte Container, die typische Muster in wenigen Zeilen lösen – ganz ohne externe Pakete. In diesem Beitrag schauen wir uns die vier nützlichsten Typen an: Counter, defaultdict, namedtuple und deque.

Counter: Elemente zählen leicht gemacht

Häufig möchtest du wissen, wie oft ein Wert in einer Sequenz vorkommt. Ohne Hilfsmittel schreibst du dafür schnell eine umständliche Schleife mit einem Dictionary. Counter erledigt das in einer Zeile und bringt gleich praktische Methoden mit.

from collections import Counter

woerter = "apfel banane apfel kirsche banane apfel".split()
zaehler = Counter(woerter)

print(zaehler)                 # Counter({'apfel': 3, 'banane': 2, 'kirsche': 1})
print(zaehler["apfel"])        # 3
print(zaehler.most_common(2))  # [('apfel', 3), ('banane', 2)]

Ein großer Vorteil: Fragst du einen Schlüssel ab, der nicht existiert, bekommst du 0 statt eines KeyError. Mit most_common() erhältst du die häufigsten Elemente sofort sortiert – ideal für Auswertungen wie die häufigsten Wörter in einem Text.

defaultdict: Nie wieder KeyError

Beim normalen dict musst du prüfen, ob ein Schlüssel schon existiert, bevor du ihn verwendest. Ein defaultdict legt fehlende Schlüssel automatisch mit einem Standardwert an. Du übergibst dazu eine sogenannte Factory-Funktion, etwa list oder int.

from collections import defaultdict

# Namen nach Anfangsbuchstaben gruppieren
namen = ["Anna", "Ben", "Anton", "Bea", "Clara"]
gruppen = defaultdict(list)

for name in namen:
    gruppen[name[0]].append(name)

print(gruppen["A"])  # ['Anna', 'Anton']
print(dict(gruppen)) # {'A': ['Anna', 'Anton'], 'B': ['Ben', 'Bea'], 'C': ['Clara']}

Beim ersten Zugriff auf gruppen["A"] erzeugt der defaultdict automatisch eine leere Liste, auf die du direkt append() aufrufen kannst. Mit defaultdict(int) baust du dir übrigens einen simplen Zähler, weil fehlende Schlüssel mit 0 starten.

namedtuple: Lesbare Datenstrukturen

Ein normales Tupel greifst du über Indizes an: punkt[0], punkt[1]. Das ist fehleranfällig und schwer lesbar. Mit namedtuple gibst du den Feldern Namen und behältst trotzdem die Leichtgewichtigkeit eines Tupels.

from collections import namedtuple

Punkt = namedtuple("Punkt", ["x", "y"])
p = Punkt(3, 5)

print(p.x, p.y)   # 3 5
print(p[0])       # 3  (Index-Zugriff geht weiterhin)

# Tupel sind unveränderlich - _replace erzeugt eine neue Kopie
p2 = p._replace(y=9)
print(p2)         # Punkt(x=3, y=9)

Ein namedtuple eignet sich hervorragend für kleine, unveränderliche Datensätze wie Koordinaten, Farben oder Datenbankzeilen. Wenn du mehr Funktionalität brauchst, sind dataclasses die nächste Stufe – aber für reine Datenbündel bleibt namedtuple unschlagbar kompakt.

deque: Die schnelle Warteschlange

Listen sind super, aber das Einfügen oder Entfernen am Anfang ist langsam, weil Python alle nachfolgenden Elemente verschieben muss. Eine deque (double-ended queue) ist an beiden Enden schnell und damit ideal für Warteschlangen oder Verläufe.

from collections import deque

schlange = deque(["a", "b", "c"])
schlange.append("d")        # rechts anfügen
schlange.appendleft("z")    # links anfügen
print(schlange)             # deque(['z', 'a', 'b', 'c', 'd'])

schlange.popleft()          # 'z' - vom linken Ende entfernen
print(schlange)             # deque(['a', 'b', 'c', 'd'])

# Mit maxlen entsteht ein automatischer Verlaufspuffer
verlauf = deque(maxlen=3)
for i in range(6):
    verlauf.append(i)
print(verlauf)              # deque([3, 4, 5], maxlen=3)

Besonders praktisch ist der Parameter maxlen: Ist die maximale Länge erreicht, fällt beim Anfügen automatisch das älteste Element heraus. So implementierst du mit einer Zeile einen "letzte N Einträge"-Puffer.

Wann welcher Typ?

Als Faustregel: Nutze Counter, wenn du zählst, defaultdict, wenn du gruppierst oder aggregierst, namedtuple, wenn du zusammengehörige Werte lesbar bündeln willst, und deque, wenn du oft am Anfang einer Sequenz arbeitest. Alle vier sind Teil der Standardbibliothek – ein einfaches from collections import ... genügt, kein zusätzliches Paket nötig.

Fazit

Das collections-Modul ist eine dieser Fundgruben, die viele Einsteiger übersehen. Dabei ersetzt es unzählige Zeilen handgeschriebenen Code durch klare, getestete Bausteine. Wenn du das nächste Mal eine Schleife schreibst, um Werte zu zählen oder zu gruppieren, halte kurz inne: Wahrscheinlich gibt es hier einen passenden Container, der deinen Code kürzer und lesbarer macht. Probiere die Beispiele aus und experimentiere mit den Methoden – so wird das Modul schnell zu einem festen Teil deines Werkzeugkastens.