Python & AI Tutorials Logo
Python Programmierung

16. Dictionaries: Schlüssel auf Werte abbilden

In den vorherigen Kapiteln haben wir etwas über Listen und Tupel gelernt—Sammlungen, die Elemente in einer bestimmten Reihenfolge speichern und uns den Zugriff nach Position ermöglichen. Aber was ist, wenn wir Informationen über etwas Sinnvolleres als eine Zahl nachschlagen möchten? Was ist, wenn wir die Note eines Schülers anhand seines Namens finden möchten, oder den Preis eines Produkts anhand seiner ID, oder die Definition eines Wortes anhand des Wortes selbst?

Hier kommen Dictionaries(dictionary) ins Spiel. Ein Dictionary ist Pythons integrierte Datenstruktur zum Speichern von Schlüssel-Wert-Paaren(key-value pairs). Statt auf Elemente über ihre Position zuzugreifen (wie grades[0]), greifen wir über ihren Schlüssel(key) darauf zu (wie grades["Alice"]). Das macht Dictionaries unglaublich leistungsfähig, wenn es darum geht, Daten in realen Programmen zu organisieren und abzurufen.

Stellen Sie sich ein Dictionary wie ein echtes Wörterbuch oder ein Telefonbuch vor: Sie schlagen ein Wort (den Schlüssel) nach, um seine Definition (den Wert) zu finden, oder Sie schlagen einen Namen nach, um eine Telefonnummer zu finden. Python-Dictionaries funktionieren genauso—sie bilden Schlüssel auf Werte ab und ermöglichen schnelle Nachschlagevorgänge sowie eine flexible Datenorganisation.

16.1) Dictionaries erstellen und auf Werte zugreifen

16.1.1) Was ist ein Dictionary?

Ein Dictionary(dictionary) ist eine Sammlung von Schlüssel-Wert-Paaren(key-value pairs). Jeder Schlüssel ist mit einem Wert verknüpft, und Sie verwenden den Schlüssel, um den Wert abzurufen. Schlüssel müssen innerhalb eines Dictionaries eindeutig sein—Sie können nicht zwei Einträge mit demselben Schlüssel haben. Werte hingegen können doppelt vorkommen.

Hier ist die grundlegende Struktur:

  • Schlüssel(Keys): Eindeutige Kennungen zum Nachschlagen von Werten (wie Namen, IDs oder Labels)
  • Werte(Values): Die Daten, die jedem Schlüssel zugeordnet sind (wie Noten, Preise oder Beschreibungen)

Dictionaries sind:

  • Veränderlich(mutable): Sie können nach der Erstellung Schlüssel-Wert-Paare hinzufügen, ändern oder entfernen
  • Ungeordnet(unordered) (in Python 3.6 und früher) oder Einfügereihenfolge(insertion-ordered) (in Python 3.7+): Obwohl modernes Python die Reihenfolge beibehält, in der Sie Elemente hinzufügen, sollten Sie Dictionaries als Sammlungen betrachten, bei denen Sie über Schlüssel und nicht über Positionen zugreifen
  • Dynamisch(dynamic): Sie können je nach Bedarf wachsen und schrumpfen

16.1.2) Leere und einfache Dictionaries erstellen

Die einfachste Art, ein Dictionary zu erstellen, ist die Verwendung geschweifter Klammern {} mit Schlüssel-Wert-Paaren, die durch Doppelpunkte getrennt sind:

python
# Leeres Dictionary
empty_dict = {}
print(empty_dict)  # Output: {}
print(type(empty_dict))  # Output: <class 'dict'>
 
# Dictionary mit Schülernoten
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
print(grades)  # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}
 
# Dictionary mit Produktpreisen
prices = {"apple": 0.50, "banana": 0.30, "orange": 0.75}
print(prices)  # Output: {'apple': 0.5, 'banana': 0.3, 'orange': 0.75}

Beachten Sie die Syntax: Jedes Schlüssel-Wert-Paar wird als key: value geschrieben, und die Paare werden durch Kommas getrennt. Die Schlüssel hier sind Strings ("Alice", "apple"), und die Werte sind Zahlen, aber sowohl Schlüssel als auch Werte können viele unterschiedliche Typen haben.

Sie können ein Dictionary auch mit dem dict()-Konstruktor erstellen:

python
# Verwendung von dict() mit Keyword-Argumenten
student = dict(name="Alice", age=20, major="Computer Science")
print(student)  # Output: {'name': 'Alice', 'age': 20, 'major': 'Computer Science'}
 
# Verwendung von dict() mit einer Liste von Tupeln
colors = dict([("red", "#FF0000"), ("green", "#00FF00"), ("blue", "#0000FF")])
print(colors)  # Output: {'red': '#FF0000', 'green': '#00FF00', 'blue': '#0000FF'}

Der dict()-Konstruktor ist nützlich, wenn Sie Dictionaries aus anderen Datenstrukturen aufbauen oder wenn Sie Python-Bezeichner als Schlüssel verwenden möchten (ohne Anführungszeichen).

16.1.3) Zugriff auf Werte über den Schlüssel

Um einen Wert aus einem Dictionary abzurufen, verwenden Sie eckige Klammern mit dem Schlüssel:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Auf einzelne Werte zugreifen
alice_grade = grades["Alice"]
print(alice_grade)  # Output: 95
 
bob_grade = grades["Bob"]
print(bob_grade)  # Output: 87

Das ist die direkteste Art, auf Dictionary-Werte zuzugreifen. Wenn Sie jedoch versuchen, auf einen Schlüssel zuzugreifen, der nicht existiert, löst Python einen KeyError aus:

python
grades = {"Alice": 95, "Bob": 87}
 
# WARNING: KeyError - for demonstration only
# print(grades["David"])  # PROBLEM: KeyError: 'David'

Dieser Fehler tritt auf, weil "David" kein Schlüssel im Dictionary ist. Wie Sie das sicher behandeln, lernen wir im nächsten Unterabschnitt.

16.1.4) Sicherer Zugriff mit get()

Um KeyError zu vermeiden, wenn ein Schlüssel möglicherweise nicht existiert, verwenden Sie die Methode get(). Sie gibt None (oder einen von Ihnen angegebenen Standardwert) zurück, wenn der Schlüssel nicht gefunden wird:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Sicherer Zugriff mit get()
alice_grade = grades.get("Alice")
print(alice_grade)  # Output: 95
 
# Schlüssel existiert nicht - gibt None zurück
david_grade = grades.get("David")
print(david_grade)  # Output: None
 
# Einen Standardwert angeben
david_grade = grades.get("David", 0)
print(david_grade)  # Output: 0
 
# get() in bedingter Logik verwenden
if grades.get("Eve") is None:
    print("Eve is not in the grade book")  # Output: Eve is not in the grade book

Die Methode get() ist sicherer als der direkte Zugriff per eckigen Klammern, wenn Sie nicht sicher sind, ob ein Schlüssel existiert. Das zweite Argument von get() ist der Standardwert, der zurückgegeben werden soll, wenn der Schlüssel fehlt—wenn Sie keinen angeben, ist der Standard None.

Hier ist ein praktisches Beispiel, das zeigt, wann get() nützlich ist:

python
# Schülerdatenbank mit optionalen Informationen
students = {
    "Alice": {"age": 20, "major": "CS"},
    "Bob": {"age": 19},  # Bob hat noch keinen Studiengang angegeben
    "Charlie": {"major": "Math"}  # Charlies Alter ist nicht erfasst
}
 
# Sicherer Zugriff auf möglicherweise fehlende Informationen
for name in ["Alice", "Bob", "Charlie"]:
    student = students[name]
    age = student.get("age", "Unknown")
    major = student.get("major", "Undeclared")
    print(f"{name}: Age {age}, Major {major}")
 
# Output:
# Alice: Age 20, Major CS
# Bob: Age 19, Major Undeclared
# Charlie: Age Unknown, Major Math

16.1.5) Gültige Schlüsseltypen

Dictionary-Schlüssel müssen hashbar(hashable) sein—ein technischer Begriff, der bedeutet, dass sich der Wert des Schlüssels nicht ändern darf. In der Praxis bedeutet das:

Gültige Schlüsseltypen (unveränderlich/immutable):

  • Strings: "name", "id_123"
  • Zahlen: 42, 3.14
  • Tupel (wenn sie nur unveränderliche Elemente enthalten): (1, 2), ("x", "y")
  • Booleans: True, False
  • None

Ungültige Schlüsseltypen (veränderlich/mutable):

  • Listen: [1, 2, 3] kann kein Schlüssel sein
  • Dictionaries: {"a": 1} kann kein Schlüssel sein
  • Sets: {1, 2, 3} kann kein Schlüssel sein
python
# Gültige Schlüssel
valid_dict = {
    "name": "Alice",           # String-Schlüssel
    42: "answer",              # Integer-Schlüssel
    3.14: "pi",                # Float-Schlüssel
    (1, 2): "coordinates",     # Tupel-Schlüssel
    True: "yes",               # Boolean-Schlüssel
    None: "nothing"            # None-Schlüssel
}
print(valid_dict["name"])      # Output: Alice
print(valid_dict[42])          # Output: answer
print(valid_dict[(1, 2)])      # Output: coordinates
 
# WARNING: Ungültige Schlüssel - nur zur Demonstration
# invalid_dict = {[1, 2]: "list key"}  # PROBLEM: TypeError: unhashable type: 'list'
# invalid_dict = {{1, 2}: "set key"}   # PROBLEM: TypeError: unhashable type: 'set'

Häufiger Anfängerfehler(Common Beginner Mistake): Ein häufiger Fehler ist, zu versuchen, eine Liste als Dictionary-Schlüssel zu verwenden, weil es logisch erscheint. Zum Beispiel möchten Sie vielleicht Koordinaten [x, y] als Schlüssel verwenden, um Standortdaten zu speichern. Wenn Python TypeError: unhashable type: 'list' ausgibt, verstehen Anfänger oft nicht, warum—schließlich enthält die Liste genau die Daten, die sie als Schlüssel verwenden möchten.

Der Grund ist, dass Listen veränderlich sind (sie können sich ändern), und Python verlangt, dass Dictionary-Schlüssel stabil und unveränderlich sind. Wenn Sie etwas Listen-Ähnliches als Schlüssel benötigen, konvertieren Sie es zuerst in ein Tupel: tuple([1, 2]) wird zu (1, 2), und das kann als Schlüssel verwendet werden. Tupel sind unveränderlich, daher funktionieren sie perfekt:

python
# Falsch: Versuch, eine Liste als Schlüssel zu verwenden
# locations = {[0, 0]: "origin", [1, 0]: "east"}  # PROBLEM: TypeError
 
# Richtig: in Tupel konvertieren
locations = {(0, 0): "origin", (1, 0): "east", (0, 1): "north"}
print(locations[(0, 0)])  # Output: origin
print(locations[(1, 0)])  # Output: east

Werte hingegen können jeden Typ haben—veränderlich oder unveränderlich:

python
# Werte können jeden Typ haben
flexible_dict = {
    "numbers": [1, 2, 3],              # Listenwert
    "nested": {"a": 1, "b": 2},        # Dictionary-Wert
    "function": len,                    # Funktionswert
    "mixed": (1, [2, 3], {"x": 4})     # Tupel, das veränderliche Elemente enthält
}
print(flexible_dict["numbers"])        # Output: [1, 2, 3]
print(flexible_dict["nested"]["a"])    # Output: 1

Wir werden Hashbarkeit im Kapitel 17 genauer untersuchen, aber fürs Erste gilt: Verwenden Sie unveränderliche Typen (Strings, Zahlen, Tupel) als Schlüssel, dann sind Sie auf der sicheren Seite.

16.2) Dictionary-Einträge hinzufügen und aktualisieren

16.2.1) Neue Schlüssel-Wert-Paare hinzufügen

Einen neuen Eintrag zu einem Dictionary hinzuzufügen ist unkompliziert—weisen Sie einfach einem neuen Schlüssel einen Wert zu:

python
grades = {"Alice": 95, "Bob": 87}
print(grades)  # Output: {'Alice': 95, 'Bob': 87}
 
# Einen neuen Schüler hinzufügen
grades["Charlie"] = 92
print(grades)  # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}
 
# Einen weiteren Schüler hinzufügen
grades["Diana"] = 88
print(grades)  # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92, 'Diana': 88}

Wenn der Schlüssel nicht existiert, erstellt Python ihn. Wenn er existiert, aktualisiert Python den Wert (das behandeln wir als Nächstes).

16.2.2) Vorhandene Werte aktualisieren

Um einen Wert zu aktualisieren, weisen Sie einfach einem bestehenden Schlüssel einen neuen Wert zu:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
print(grades)  # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}
 
# Bobs Note aktualisieren
grades["Bob"] = 90
print(grades)  # Output: {'Alice': 95, 'Bob': 90, 'Charlie': 92}
 
# Mehrere Noten aktualisieren
grades["Alice"] = 98
grades["Charlie"] = 94
print(grades)  # Output: {'Alice': 98, 'Bob': 90, 'Charlie': 94}

Python unterscheidet nicht zwischen Hinzufügen und Aktualisieren—die Syntax ist identisch. Wenn der Schlüssel existiert, wird der Wert aktualisiert; andernfalls wird ein neuer Eintrag erstellt.

Hier ist ein praktisches Beispiel, das sowohl Hinzufügen als auch Aktualisieren zeigt:

python
# Bestand verfolgen
inventory = {"apple": 50, "banana": 30}
print("Initial inventory:", inventory)  # Output: Initial inventory: {'apple': 50, 'banana': 30}
 
# Äpfel nachfüllen (vorhandenen Eintrag aktualisieren)
inventory["apple"] = inventory["apple"] + 20
print("After restocking apples:", inventory)  # Output: After restocking apples: {'apple': 70, 'banana': 30}
 
# Neues Produkt hinzufügen (neuen Schlüssel hinzufügen)
inventory["orange"] = 40
print("After adding oranges:", inventory)  # Output: After adding oranges: {'apple': 70, 'banana': 30, 'orange': 40}
 
# Einige Bananen verkaufen (vorhandenen Eintrag aktualisieren)
inventory["banana"] = inventory["banana"] - 10
print("After selling bananas:", inventory)  # Output: After selling bananas: {'apple': 70, 'banana': 20, 'orange': 40}

16.2.3) update() verwenden, um Dictionaries zusammenzuführen

Die Methode update() fügt mehrere Schlüssel-Wert-Paare auf einmal hinzu oder führt ein anderes Dictionary in das aktuelle zusammen:

python
grades = {"Alice": 95, "Bob": 87}
print(grades)  # Output: {'Alice': 95, 'Bob': 87}
 
# Mehrere Schüler auf einmal hinzufügen
new_students = {"Charlie": 92, "Diana": 88}
grades.update(new_students)
print(grades)  # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92, 'Diana': 88}
 
# Vorhandene aktualisieren und neue hinzufügen
more_updates = {"Bob": 90, "Eve": 85}  # Bobs Note ändert sich, Eve ist neu
grades.update(more_updates)
print(grades)  # Output: {'Alice': 95, 'Bob': 90, 'Charlie': 92, 'Diana': 88, 'Eve': 85}

Die Methode update() verändert das Dictionary direkt (in place). Wenn ein Schlüssel bereits existiert, wird sein Wert aktualisiert; wenn nicht, wird das Schlüssel-Wert-Paar hinzugefügt.

Sie können update() auch Keyword-Argumente übergeben:

python
student = {"name": "Alice", "age": 20}
print(student)  # Output: {'name': 'Alice', 'age': 20}
 
# Mit Keyword-Argumenten aktualisieren
student.update(age=21, major="Computer Science")
print(student)  # Output: {'name': 'Alice', 'age': 21, 'major': 'Computer Science'}

Hier ist ein praktisches Beispiel zum Zusammenführen von Konfigurationseinstellungen:

python
# Standardeinstellungen
config = {
    "theme": "light",
    "font_size": 12,
    "auto_save": True
}
 
# Benutzereinstellungen (überschreiben einige Defaults)
user_prefs = {
    "theme": "dark",
    "font_size": 14
}
 
# Benutzereinstellungen in config zusammenführen
config.update(user_prefs)
print(config)  # Output: {'theme': 'dark', 'font_size': 14, 'auto_save': True}

16.2.4) setdefault() verwenden, um nur hinzuzufügen, wenn der Schlüssel nicht existiert

Die Methode setdefault() ist nützlich, wenn Sie ein Schlüssel-Wert-Paar nur dann hinzufügen möchten, wenn der Schlüssel noch nicht existiert. Wenn der Schlüssel existiert, gibt sie den aktuellen Wert zurück, ohne ihn zu ändern:

python
grades = {"Alice": 95, "Bob": 87}
 
# Charlie hinzufügen (Schlüssel existiert nicht)
result = grades.setdefault("Charlie", 90)
print(result)  # Output: 90
print(grades)  # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 90}
 
# Versuch, Alice hinzuzufügen (Schlüssel existiert - keine Änderung)
result = grades.setdefault("Alice", 80)
print(result)  # Output: 95 (existing value returned)
print(grades)  # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 90} (unchanged)

Das ist besonders nützlich, wenn Sie sicherstellen möchten, dass alle erforderlichen Konfigurationsschlüssel mit Standardwerten existieren, während Sie gleichzeitig alle Werte beibehalten, die der Benutzer bereits angepasst hat:

python
# Anwendungskonfiguration mit Defaults
config = {"theme": "light", "font_size": 12}
 
# Sicherstellen, dass alle erforderlichen Einstellungen mit Defaults existieren
config.setdefault("auto_save", True)
config.setdefault("language", "en")
config.setdefault("theme", "dark")  # Wird nicht geändert - existiert bereits
 
print(config)
# Output: {'theme': 'light', 'font_size': 12, 'auto_save': True, 'language': 'en'}
 
# Jetzt sicher auf alle Einstellungen zugreifen
print(f"Theme: {config['theme']}")           # Output: Theme: light
print(f"Auto-save: {config['auto_save']}")   # Output: Auto-save: True
print(f"Language: {config['language']}")     # Output: Language: en

16.3) Dictionary-Einträge mit del und pop() entfernen

16.3.1) Einträge mit del entfernen

Die Anweisung del entfernt ein Schlüssel-Wert-Paar aus einem Dictionary:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
print(grades)  # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92, 'Diana': 88}
 
# Charlie entfernen
del grades["Charlie"]
print(grades)  # Output: {'Alice': 95, 'Bob': 87, 'Diana': 88}
 
# Einen weiteren Schüler entfernen
del grades["Bob"]
print(grades)  # Output: {'Alice': 95, 'Diana': 88}

Wenn Sie versuchen, einen Schlüssel zu löschen, der nicht existiert, löst Python einen KeyError aus:

python
grades = {"Alice": 95, "Bob": 87}
 
# WARNING: KeyError - for demonstration only
# del grades["Charlie"]  # PROBLEM: KeyError: 'Charlie'

Um einen Schlüssel sicher zu löschen, der möglicherweise nicht existiert, prüfen Sie vorher:

python
grades = {"Alice": 95, "Bob": 87}
 
# Sicheres Löschen
if "Charlie" in grades:
    del grades["Charlie"]
else:
    print("Charlie not found")  # Output: Charlie not found

16.3.2) Mit pop() entfernen und zurückgeben

Die Methode pop() entfernt einen Schlüssel und gibt seinen Wert zurück. Das ist nützlich, wenn Sie einen Eintrag sowohl entfernen als auch seinen Wert verwenden müssen:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
print(grades)  # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}
 
# Bob entfernen und seine Note holen
bob_grade = grades.pop("Bob")
print(bob_grade)  # Output: 87
print(grades)  # Output: {'Alice': 95, 'Charlie': 92}
 
# Entfernen und den Wert verwenden
charlie_grade = grades.pop("Charlie")
print(f"Charlie's final grade was {charlie_grade}")  # Output: Charlie's final grade was 92
print(grades)  # Output: {'Alice': 95}

Wie del löst pop() einen KeyError aus, wenn der Schlüssel nicht existiert. Sie können jedoch einen Standardwert angeben, der stattdessen zurückgegeben wird:

python
grades = {"Alice": 95, "Bob": 87}
 
# pop mit Standardwert (Schlüssel existiert nicht)
diana_grade = grades.pop("Diana", 0)
print(diana_grade)  # Output: 0
print(grades)  # Output: {'Alice': 95, 'Bob': 87} (unchanged)
 
# pop mit Standardwert (Schlüssel existiert)
alice_grade = grades.pop("Alice", 0)
print(alice_grade)  # Output: 95
print(grades)  # Output: {'Bob': 87}

16.3.3) Alle Einträge mit clear() entfernen

Die Methode clear() entfernt alle Schlüssel-Wert-Paare aus einem Dictionary und lässt es leer zurück:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
print(grades)  # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}
 
# Alle Einträge löschen
grades.clear()
print(grades)  # Output: {}
print(len(grades))  # Output: 0

Das ist expliziter als das Neuzuweisen zu einem leeren Dictionary (grades = {}), insbesondere wenn andere Variablen auf dasselbe Dictionary verweisen:

python
# Den Unterschied demonstrieren
grades = {"Alice": 95, "Bob": 87}
backup = grades  # backup verweist auf dasselbe Dictionary
 
# clear() verwenden - betrifft beide Variablen
grades.clear()
print(grades)   # Output: {}
print(backup)   # Output: {} (same dictionary was cleared)
 
# Für das nächste Beispiel zurücksetzen
grades = {"Alice": 95, "Bob": 87}
backup = grades
 
# Neuzuweisung - betrifft nur grades
grades = {}
print(grades)   # Output: {}
print(backup)   # Output: {'Alice': 95, 'Bob': 87} (different dictionary now)

Dieses Verhalten werden wir in Kapitel 18 genauer untersuchen, wenn wir über Referenzsemantik sprechen, aber fürs Erste gilt: clear() leert das bestehende Dictionary, während eine Neuzuweisung ein neues leeres Dictionary erstellt.

16.4) Dictionary-View-Objekte: keys(), values() und items()

16.4.1) Dictionary-Views verstehen

Dictionaries stellen drei Methoden bereit, die View-Objekte(view objects) zurückgeben—spezielle Objekte, die eine dynamische Ansicht der Schlüssel, Werte oder Schlüssel-Wert-Paare eines Dictionaries liefern. Diese Views spiegeln Änderungen am Dictionary automatisch wider:

  • keys(): Gibt eine View aller Schlüssel zurück
  • values(): Gibt eine View aller Werte zurück
  • items(): Gibt eine View aller Schlüssel-Wert-Paare zurück (als Tupel)
python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Views holen
keys_view = grades.keys()
values_view = grades.values()
items_view = grades.items()
 
print(keys_view)    # Output: dict_keys(['Alice', 'Bob', 'Charlie'])
print(values_view)  # Output: dict_values([95, 87, 92])
print(items_view)   # Output: dict_items([('Alice', 95), ('Bob', 87), ('Charlie', 92)])

Das sind keine Listen—es sind View-Objekte. Sie können sie aber bei Bedarf in Listen umwandeln:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Views in Listen umwandeln
keys_list = list(grades.keys())
values_list = list(grades.values())
items_list = list(grades.items())
 
print(keys_list)    # Output: ['Alice', 'Bob', 'Charlie']
print(values_list)  # Output: [95, 87, 92]
print(items_list)   # Output: [('Alice', 95), ('Bob', 87), ('Charlie', 92)]

16.4.2) Views sind dynamisch

View-Objekte spiegeln Änderungen am Dictionary automatisch wider:

python
grades = {"Alice": 95, "Bob": 87}
 
# Eine View erstellen
keys_view = grades.keys()
print(keys_view)  # Output: dict_keys(['Alice', 'Bob'])
 
# Das Dictionary ändern
grades["Charlie"] = 92
print(keys_view)  # Output: dict_keys(['Alice', 'Bob', 'Charlie'])
 
# Einen Eintrag entfernen
del grades["Bob"]
print(keys_view)  # Output: dict_keys(['Alice', 'Charlie'])

Dieses dynamische Verhalten ist nützlich, wenn Sie mit Dictionary-Inhalten arbeiten müssen, die sich ändern können. Wenn Sie jedoch eine Momentaufnahme benötigen, die sich nicht ändert, konvertieren Sie die View in eine Liste:

python
grades = {"Alice": 95, "Bob": 87}
 
# Eine Momentaufnahme erstellen
keys_snapshot = list(grades.keys())
print(keys_snapshot)  # Output: ['Alice', 'Bob']
 
# Das Dictionary ändern
grades["Charlie"] = 92
print(keys_snapshot)  # Output: ['Alice', 'Bob'] (unchanged)

Dynamisches Update

Kein Effekt

Dictionary

View-Objekt

Listen-Momentaufnahme

Dictionary ändern

16.4.3) Mit keys() arbeiten

Die Methode keys() gibt eine View aller Dictionary-Schlüssel zurück. Das ist nützlich, um zu prüfen, welche Schlüssel existieren, oder um über sie zu iterieren:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Alle Schlüssel holen
keys = grades.keys()
print(keys)  # Output: dict_keys(['Alice', 'Bob', 'Charlie'])
 
# Prüfen, ob ein Schlüssel existiert
if "Alice" in keys:
    print("Alice is in the grade book")  # Output: Alice is in the grade book
 
# Schlüssel zählen
print(f"Number of students: {len(keys)}")  # Output: Number of students: 3

Sie können die Mitgliedschaft auch direkt am Dictionary prüfen, ohne keys() aufzurufen:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Diese sind äquivalent
if "Alice" in grades.keys():
    print("Found (using keys())")
 
if "Alice" in grades:
    print("Found (direct check)")  # This is more common and concise
 
# Output:
# Found (using keys())
# Found (direct check)

16.4.4) Mit values() arbeiten

Die Methode values() gibt eine View aller Dictionary-Werte zurück. Das ist nützlich, wenn Sie Werte verarbeiten müssen, ohne sich um ihre Schlüssel zu kümmern:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
 
# Alle Werte holen
values = grades.values()
print(values)  # Output: dict_values([95, 87, 92, 88])
 
# Statistiken berechnen
total = sum(values)
count = len(values)
average = total / count
 
print(f"Total points: {total}")      # Output: Total points: 362
print(f"Number of students: {count}")  # Output: Number of students: 4
print(f"Average grade: {average}")   # Output: Average grade: 90.5
 
# Höchste und niedrigste Note finden
print(f"Highest grade: {max(values)}")  # Output: Highest grade: 95
print(f"Lowest grade: {min(values)}")   # Output: Lowest grade: 87

16.4.5) Mit items() arbeiten

Die Methode items() gibt eine View von Schlüssel-Wert-Paaren als Tupel zurück. Das ist die am häufigsten verwendete View, weil Sie sowohl Schlüssel als auch Werte erhalten:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Alle Schlüssel-Wert-Paare holen
items = grades.items()
print(items)  # Output: dict_items([('Alice', 95), ('Bob', 87), ('Charlie', 92)])
 
# In eine Liste konvertieren, um die Tupel klar zu sehen
items_list = list(items)
print(items_list)  # Output: [('Alice', 95), ('Bob', 87), ('Charlie', 92)]
 
# Auf einzelne Tupel zugreifen
first_item = items_list[0]
print(first_item)        # Output: ('Alice', 95)
print(first_item[0])     # Output: Alice
print(first_item[1])     # Output: 95

Die items()-View ist besonders nützlich für Iterationen, die wir im nächsten Abschnitt detailliert behandeln. Hier ist eine Vorschau:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Jedes Schlüssel-Wert-Paar verarbeiten
for name, grade in grades.items():
    print(f"{name}: {grade}")
 
# Output:
# Alice: 95
# Bob: 87
# Charlie: 92

16.5) Über Schlüssel, Werte und Items iterieren

16.5.1) Über Schlüssel iterieren (Standardverhalten)

Wenn Sie direkt über ein Dictionary mit einer for-Schleife(loop) iterieren, iterieren Sie über seine Schlüssel:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Über Schlüssel iterieren (implizit)
for name in grades:
    print(name)
 
# Output:
# Alice
# Bob
# Charlie

Das ist äquivalent zur Iteration über grades.keys():

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Über Schlüssel iterieren (explizit)
for name in grades.keys():
    print(name)
 
# Output:
# Alice
# Bob
# Charlie

Beide Ansätze funktionieren identisch. Die implizite Version (ohne .keys()) ist gebräuchlicher und kürzer.

Hier ist ein praktisches Beispiel, das Schlüssel verwendet, um auf Werte zuzugreifen:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
 
# Schüler finden, die bestanden haben (grade >= 90)
passing_students = []
for name in grades:
    if grades[name] >= 90:
        passing_students.append(name)
 
print("Students who passed:", passing_students)  # Output: Students who passed: ['Alice', 'Charlie']

16.5.2) Über Werte iterieren

Um nur über die Werte zu iterieren, verwenden Sie values():

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
 
# Über Werte iterieren
for grade in grades.values():
    print(grade)
 
# Output:
# 95
# 87
# 92
# 88

Das ist nützlich, wenn Sie Werte verarbeiten müssen, aber es Ihnen egal ist, welchem Schlüssel sie zugeordnet sind:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
 
# Summe und Durchschnitt berechnen
total = 0
count = 0
for grade in grades.values():
    total = total + grade
    count = count + 1
 
average = total / count
print(f"Class average: {average}")  # Output: Class average: 90.5
 
# Prüfen, ob alle Schüler bestanden haben
all_passed = True
for grade in grades.values():
    if grade < 60:
        all_passed = False
        break
 
if all_passed:
    print("All students passed!")  # Output: All students passed!

16.5.3) Über Schlüssel-Wert-Paare mit items() iterieren

Das häufigste und nützlichste Iterationsmuster ist die Verwendung von items(), um sowohl Schlüssel als auch Werte zu erhalten:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Über Schlüssel-Wert-Paare iterieren
for name, grade in grades.items():
    print(f"{name} scored {grade}")
 
# Output:
# Alice scored 95
# Bob scored 87
# Charlie scored 92

Beachten Sie das Entpacken von Tupeln: for name, grade in grades.items(). Jedes Element ist ein Tupel wie ("Alice", 95), und wir entpacken es in zwei Variablen. Das ist viel besser lesbar als der Zugriff über Tupel-Indizes:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Ohne Entpacken (weniger lesbar)
for item in grades.items():
    print(f"{item[0]} scored {item[1]}")
 
# Mit Entpacken (besser lesbar)
for name, grade in grades.items():
    print(f"{name} scored {grade}")
 
# Both produce the same output:
# Alice scored 95
# Bob scored 87
# Charlie scored 92

16.5.4) Dictionaries während der Iteration verändern

Warnung(Warning): Die Größe eines Dictionaries (Hinzufügen oder Entfernen von Schlüsseln) während der Iteration zu verändern, kann Fehler oder unerwartetes Verhalten verursachen:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# WARNING: RuntimeError - for demonstration only
# for name in grades:
#     if grades[name] < 90:
#         del grades[name]  # PROBLEM: RuntimeError: dictionary changed size during iteration

In modernem Python (3.7+) löst das sofort einen RuntimeError aus, sobald Sie versuchen, die Größe des Dictionaries zu ändern. Python erkennt die Änderung und stoppt die Ausführung, um unvorhersehbares Verhalten zu verhindern.

In älteren Python-Versionen konnte das dazu führen, dass der Iterator:

  • Elemente überspringt, die er verarbeiten sollte
  • Dasselbe Element zweimal verarbeitet
  • Inkonsistente Ergebnisse produziert

Deshalb schlägt Python jetzt schnell fehl (fail fast) mit einer klaren Fehlermeldung.

Wenn Sie ein Dictionary während der Iteration verändern müssen, iterieren Sie über eine Kopie der Schlüssel:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
 
# Sicher: über eine Kopie der Schlüssel iterieren
for name in list(grades.keys()):
    if grades[name] < 90:
        del grades[name]
 
print(grades)  # Output: {'Alice': 95, 'Charlie': 92}

Oder erstellen Sie ein neues Dictionary mit nur den Einträgen, die Sie behalten möchten:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
 
# Ein neues Dictionary mit gefilterten Einträgen erstellen
high_grades = {}
for name, grade in grades.items():
    if grade >= 90:
        high_grades[name] = grade
 
print(high_grades)  # Output: {'Alice': 95, 'Charlie': 92}

Der zweite Ansatz ist oft klarer und sicherer. Wir werden in Kapitel 35 noch elegantere Wege kennenlernen, um das mit Dictionary-Comprehensions zu tun.

16.6) Häufige Dictionary-Methoden

16.6.1) Auf Schlüssel prüfen mit in und not in

Die Operatoren in und not in prüfen, ob ein Schlüssel in einem Dictionary existiert:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
 
# Prüfen, ob Schlüssel existieren
if "Alice" in grades:
    print("Alice is in the grade book")  # Output: Alice is in the grade book
 
if "David" not in grades:
    print("David is not in the grade book")  # Output: David is not in the grade book

Das ist die bevorzugte Art, das Vorhandensein eines Schlüssels zu prüfen, bevor Sie auf Werte zugreifen. Es ist besser lesbar und Pythonic als get() zu verwenden und auf None zu prüfen:

python
grades = {"Alice": 95, "Bob": 87}
 
# Bevorzugt: in verwenden
if "Alice" in grades:
    print(f"Alice's grade: {grades['Alice']}")  # Output: Alice's grade: 95
 
# Alternative: get() verwenden und auf None prüfen
if grades.get("Alice") is not None:
    print(f"Alice's grade: {grades['Alice']}")  # Output: Alice's grade: 95

16.6.2) Anzahl der Einträge mit len() ermitteln

Die Funktion len() gibt die Anzahl der Schlüssel-Wert-Paare in einem Dictionary zurück:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92}
print(len(grades))  # Output: 3
 
# Leeres Dictionary
empty = {}
print(len(empty))  # Output: 0
 
# Nach Änderungen
grades["Diana"] = 88
print(len(grades))  # Output: 4
 
del grades["Bob"]
print(len(grades))  # Output: 3

Das ist nützlich, um zu prüfen, ob ein Dictionary leer ist, oder um Statistiken zu berichten:

python
grades = {"Alice": 95, "Bob": 87, "Charlie": 92, "Diana": 88}
 
if len(grades) == 0:
    print("No students in grade book")
else:
    total = sum(grades.values())
    average = total / len(grades)
    print(f"{len(grades)} students, average grade: {average}")
    # Output: 4 students, average grade: 90.5

16.6.3) Dictionaries kopieren mit copy()

Die Methode copy() erstellt eine flache Kopie(shallow copy) eines Dictionaries—ein neues Dictionary mit denselben Schlüssel-Wert-Paaren:

python
original = {"Alice": 95, "Bob": 87}
duplicate = original.copy()
 
print(original)   # Output: {'Alice': 95, 'Bob': 87}
print(duplicate)  # Output: {'Alice': 95, 'Bob': 87}
 
# Die Kopie verändern
duplicate["Charlie"] = 92
print(original)   # Output: {'Alice': 95, 'Bob': 87} (unchanged)
print(duplicate)  # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}

Das unterscheidet sich von einer einfachen Zuweisung, die eine Referenz auf dasselbe Dictionary erstellt:

python
original = {"Alice": 95, "Bob": 87}
reference = original  # Keine Kopie - dasselbe Dictionary
 
# Über die Referenz verändern
reference["Charlie"] = 92
print(original)   # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92} (changed!)
print(reference)  # Output: {'Alice': 95, 'Bob': 87, 'Charlie': 92}

Flache vs. tiefe Kopien werden wir in Kapitel 18 im Detail untersuchen. Fürs Erste gilt: Verwenden Sie copy(), wenn Sie ein unabhängiges Duplikat eines Dictionaries möchten.

16.6.4) Dictionaries mit dem | Operator zusammenführen (Python 3.9+)

Python 3.9 hat den Operator | zum Zusammenführen von Dictionaries eingeführt. Der Operator | erstellt ein neues Dictionary, das alle Schlüssel aus beiden Dictionaries kombiniert. Bei doppelten Schlüsseln überschreibt der Wert der rechten Seite den Wert der linken Seite. Beide ursprünglichen Dictionaries bleiben unverändert.

python
defaults = {"theme": "light", "font_size": 12, "auto_save": True}
user_prefs = {"theme": "dark", "font_size": 14}
 
# Dictionaries zusammenführen (user_prefs überschreibt defaults)
config = defaults | user_prefs
print(config)  # Output: {'theme': 'dark', 'font_size': 14, 'auto_save': True}
 
# Ursprüngliche Dictionaries unverändert
print(defaults)    # Output: {'theme': 'light', 'font_size': 12, 'auto_save': True}
print(user_prefs)  # Output: {'theme': 'dark', 'font_size': 14}

Hier ist ein weiteres Beispiel, das zeigt, wie das zum Kombinieren von Daten aus mehreren Quellen nützlich ist:

python
# Produktinformationen von zwei Lieferanten
supplier_a = {
    "laptop": {"price": 999.99, "stock": 15},
    "mouse": {"price": 29.99, "stock": 50}
}
 
supplier_b = {
    "laptop": {"price": 949.99, "stock": 20},  # Besserer Preis und Bestand
    "keyboard": {"price": 79.99, "stock": 30}
}
 
# Zusammenführen: supplier_b überschreibt supplier_a bei übereinstimmenden Produkten
combined = supplier_a | supplier_b
print(combined)
# Output: {'laptop': {'price': 949.99, 'stock': 20}, 'mouse': {'price': 29.99, 'stock': 50}, 'keyboard': {'price': 79.99, 'stock': 30}}
 
# Now we have laptop from supplier_b (better deal), mouse from supplier_a, and keyboard from supplier_b

Der Operator |= führt in place zusammen (verändert das linke Dictionary):

python
config = {"theme": "light", "font_size": 12, "auto_save": True}
user_prefs = {"theme": "dark", "font_size": 14}
 
# In place zusammenführen
config |= user_prefs
print(config)  # Output: {'theme': 'dark', 'font_size': 14, 'auto_save': True}

Das entspricht der Verwendung von update(), ist aber kürzer:

python
config = {"theme": "light", "font_size": 12}
user_prefs = {"theme": "dark", "font_size": 14}
 
# Diese sind äquivalent
config.update(user_prefs)
# config |= user_prefs
 
print(config)  # Output: {'theme': 'dark', 'font_size': 14}

16.7) Verschachtelte Dictionaries für strukturierte Daten

16.7.1) Verschachtelte Dictionaries erstellen

Warum verschachtelte Dictionaries verwenden? Stellen Sie sich vor, Sie verfolgen Schülerinformationen. Sie könnten separate Dictionaries erstellen: ages = {"Alice": 20, "Bob": 19}, majors = {"Alice": "CS", "Bob": "Math"}, gpas = {"Alice": 3.8, "Bob": 3.6}. Aber das wird unhandlich—Sie müssen drei Dictionaries synchron halten, und um alle Informationen für einen Schüler nachzuschlagen, brauchen Sie drei separate Nachschlagevorgänge. Verschachtelte Dictionaries lösen das, indem sie zusammengehörige Daten gruppieren: Ein Schülername wird in einem einzigen Lookup auf alle seine Informationen abgebildet.

Ein verschachteltes Dictionary(nested dictionary) ist ein Dictionary, das andere Dictionaries als Werte enthält. Das ist nützlich, um strukturierte, hierarchische Daten darzustellen:

python
# Schülerdatensätze mit mehreren Attributen
students = {
    "Alice": {
        "age": 20,
        "major": "Computer Science",
        "gpa": 3.8
    },
    "Bob": {
        "age": 19,
        "major": "Mathematics",
        "gpa": 3.6
    },
    "Charlie": {
        "age": 21,
        "major": "Physics",
        "gpa": 3.9
    }
}
 
print(students)
# Output: {'Alice': {'age': 20, 'major': 'Computer Science', 'gpa': 3.8}, 'Bob': {'age': 19, 'major': 'Mathematics', 'gpa': 3.6}, 'Charlie': {'age': 21, 'major': 'Physics', 'gpa': 3.9}}

Jeder Schülername wird auf ein weiteres Dictionary abgebildet, das seine Attribute enthält. Diese Struktur ist viel flexibler und wartbarer als separate Dictionaries für jedes Attribut zu verwenden.

students Dictionary

Alice

Bob

Charlie

age: 20

major: CS

gpa: 3.8

age: 19

major: Math

gpa: 3.6

age: 21

major: Physics

gpa: 3.9

16.7.2) Auf verschachtelte Werte zugreifen

Um auf verschachtelte Werte zuzugreifen, verwenden Sie mehrere eckige Klammern:

python
students = {
    "Alice": {"age": 20, "major": "Computer Science", "gpa": 3.8},
    "Bob": {"age": 19, "major": "Mathematics", "gpa": 3.6}
}
 
# Auf verschachtelte Werte zugreifen
alice_age = students["Alice"]["age"]
print(alice_age)  # Output: 20
 
bob_major = students["Bob"]["major"]
print(bob_major)  # Output: Mathematics
 
# In Ausdrücken verwenden
print(f"Alice is {students['Alice']['age']} years old")
# Output: Alice is 20 years old
 
print(f"Bob's GPA: {students['Bob']['gpa']}")
# Output: Bob's GPA: 3.6

Jede Klammer greift auf eine Ebene der Verschachtelung zu. Zuerst liefert students["Alice"] das innere Dictionary, dann liefert ["age"] den Alterswert aus diesem Dictionary.

16.7.3) Verschachtelte Werte sicher abrufen

Beim Zugriff auf verschachtelte Dictionaries müssen Sie prüfen, dass jede Ebene existiert:

python
students = {
    "Alice": {"age": 20, "major": "Computer Science"},
    "Bob": {"age": 19}  # Bob hat keinen Studiengang angegeben
}
 
# Unsicherer Zugriff - kann KeyError auslösen
# print(students["Bob"]["major"])  # PROBLEM: KeyError: 'major'
 
# Sicherer Zugriff mit mehreren Prüfungen
if "Bob" in students:
    if "major" in students["Bob"]:
        print(f"Bob's major: {students['Bob']['major']}")
    else:
        print("Bob hasn't declared a major")  # Output: Bob hasn't declared a major
 
# get() für sicheren verschachtelten Zugriff verwenden
bob_major = students.get("Bob", {}).get("major", "Undeclared")
print(f"Bob's major: {bob_major}")  # Output: Bob's major: Undeclared

Die get()-Kette funktioniert, weil get() ein leeres Dictionary {} zurückgibt, wenn "Bob" nicht existiert, und dann das zweite get() sicher "Undeclared" zurückgibt.

16.7.4) Verschachtelte Dictionaries verändern

Sie können Einträge in verschachtelten Dictionaries hinzufügen, aktualisieren oder entfernen:

python
students = {
    "Alice": {"age": 20, "major": "Computer Science", "gpa": 3.8},
    "Bob": {"age": 19, "major": "Mathematics", "gpa": 3.6}
}
 
# Einen verschachtelten Wert aktualisieren
students["Alice"]["gpa"] = 3.9
print(f"Alice's new GPA: {students['Alice']['gpa']}")  # Output: Alice's new GPA: 3.9
 
# Ein neues Attribut zu einem bestehenden Schüler hinzufügen
students["Bob"]["email"] = "bob@university.edu"
print(students["Bob"])
# Output: {'age': 19, 'major': 'Mathematics', 'gpa': 3.6, 'email': 'bob@university.edu'}
 
# Einen neuen Schüler mit verschachtelten Daten hinzufügen
students["Charlie"] = {
    "age": 21,
    "major": "Physics",
    "gpa": 3.7
}
print(f"Number of students: {len(students)}")  # Output: Number of students: 3
 
# Ein Attribut entfernen
del students["Bob"]["email"]
print(students["Bob"])
# Output: {'age': 19, 'major': 'Mathematics', 'gpa': 3.6}

16.7.5) Über verschachtelte Dictionaries iterieren

Sie können über verschachtelte Dictionaries mit verschachtelten Schleifen iterieren:

python
students = {
    "Alice": {"age": 20, "major": "Computer Science", "gpa": 3.8},
    "Bob": {"age": 19, "major": "Mathematics", "gpa": 3.6},
    "Charlie": {"age": 21, "major": "Physics", "gpa": 3.9}
}
 
# Über Schüler und ihre Attribute iterieren
for name, info in students.items():
    print(f"\n{name}:")
    for key, value in info.items():
        print(f"  {key}: {value}")
 
# Output:
# Alice:
#   age: 20
#   major: Computer Science
#   gpa: 3.8
#
# Bob:
#   age: 19
#   major: Mathematics
#   gpa: 3.6
#
# Charlie:
#   age: 21
#   major: Physics
#   gpa: 3.9

Hier ist ein praktisches Beispiel, um Schüler zu finden, die bestimmte Kriterien erfüllen:

python
students = {
    "Alice": {"age": 20, "major": "Computer Science", "gpa": 3.8},
    "Bob": {"age": 19, "major": "Mathematics", "gpa": 3.6},
    "Charlie": {"age": 21, "major": "Physics", "gpa": 3.9},
    "Diana": {"age": 20, "major": "Computer Science", "gpa": 3.5}
}
 
# CS-Schüler mit GPA über 3.7 finden
print("High-performing CS students:")
for name, info in students.items():
    if info["major"] == "Computer Science" and info["gpa"] >= 3.7:
        print(f"  {name} (GPA: {info['gpa']})")
 
# Output:
# High-performing CS students:
#   Alice (GPA: 3.8)

Dictionaries sind eine der leistungsfähigsten und vielseitigsten Datenstrukturen in Python. Sie ermöglichen schnelle Nachschlagevorgänge, flexible Organisation und elegante Lösungen für häufige Programmierprobleme. Während Sie weiter Python lernen, werden Sie Dictionaries überall finden—von Konfigurationseinstellungen über Datenverarbeitung bis hin zum Bau komplexer Anwendungen.

Die Muster, die wir in diesem Kapitel behandelt haben—Zählen, Gruppieren, Lookup-Tabellen und Datentransformation—bilden die Grundlage für die Arbeit mit strukturierten Daten in Python. Im nächsten Kapitel werden wir Sets untersuchen, einen weiteren Sammlungstyp, der Dictionaries beim Arbeiten mit eindeutigen, ungeordneten Daten ergänzt.

© 2025. Primesoft Co., Ltd.
support@primesoft.ai