Objektsammlungen mit Dictionaries

https://bildung.social/@oerinformatik/

https://oer-informatik.de/python_dictionary

tl/dr; (ca. 8 min Lesezeit): Häufig wollen wir Werte nicht in einzelnen Variablen speichern, sondern als zusammenhängende Struktur. Immer dann, wenn wir Key-Value-Beziehungen haben (wir also über einen bestimmten Namen auf einen Wert zugreifen wollen) sind Dictionaries die Objektsammlung der Wahl. (Zuletzt geändert am 02.03.2024)

Dieser Artikel ist Bestandteil einer Grundlagenserie zu Python:

Grundidee eines Dictionary

Dictionaries sind in Python ungeordnete, veränderliche und dynamische Objektsammlungen, in denen Werte und zugehörige Schlüssel abgespeichert werden. In anderen Programmiersprachen werden vergleichbare Datentypen häufig auch als Map oder assoziative Arrays bezeichnet.

Jedem Schlüsselwert (key) ist genau ein Datenwert (value) zugeordnet.

key \rightarrow value

Kennzeichnend für Dictionaries sind die in geschweiften Klammern gefassten Wertpaar-Auflistungen bei Instanziierung und Initialisierung. Schlüssel und Wert werden durch Doppelpunkte getrennt, die unterschiedlichen Schlüssel/Wert-Paare durch Kommata voneinander abgegrenzt. In der Python-Shell können die folgenden Beispiele direkt ohne umgebendes Programm getestet werden.

>>> person = {'Vorname':'Horst', 'Nachname': 'Müller'}

Leere Dictionaries werden nur mit geschweiften Klammern notiert:

>>> firma = {}

Um sicher zu gehen, dass es sich bei person um ein dict handelt kann in der Python-Shell mit Hilfe der type()-Funktion der Datentyp ermittelt werden:

>>> type(person)
<class 'dict'>

Der Zugriff (lesend wie schreibend) erfolgt über den in eckigen Klammern geschriebenen Schlüssel. Diese können Zeichenkennten vom Typ str sein, es können aber ebenso andere Datentypen genutzt werden.

person['Vorname'] = 'Herbert'
print(person['Vorname'])

Über diese Schreibweise können auch neue Schlüssel/Wert-Paare an das Dictonary angefügt werden, da diese Objektsammlung dynamisch ist, das heißt, dass sie zur Laufzeit des Programms wachsen/schrumpfen kann:

person['Alter'] = 44

Die Werte eines Dictionaries können auch direkt inkrementiert werden:

person['Alter'] +=1

(erneut der Hinweis: der ++-Operator, der aus anderen Programmiersprachen bekannt ist, existiert in Python nicht.)

Über print(person) können alle Eigenschaften von person angezeigt werden, die Python-Shell gibt aber auch bei Eingabe des Variablennamens die Informationen preis:

>>> person
{'Vorname': 'Herbert', 'Nachname': 'Müller', 'Alter': 45}

Iteration durch ein Dictionary

Um systematisch durch alle Schlüssel/Wert-Paare hindurch zu iterieren bietet Python eine besondere zählergesteuerte Schleife an, die jedes Paar genau einmal aufruft (in anderen Programmiersprachen entspricht das for each-Konstrukten). Jeder Schlüssel kann aufgerufen werden über:

for key in person:
    print(key)

Ausgabe:

Vorname
Nachname
Alter

Dictionaries garantieren keine Reihenfolge in der Bearbeitung. Um trotzdem eine alphabetische Reihenfolge auszugeben kann die Funktion sorted() verwendet werden.

for key in sorted(person):
    print(key)

Ausgabe:

Alter
Nachname
Vorname

Natürlich kann bei bekanntem Schlüssel dann auch der Wert ergänzt werden. Da es sich aber ggf. nicht um einen String handelt (wie zum Beispiel bei Alter) muss der Wert für die Ausgabe mit der Funktion str() in einen String umgewandelt werden:

for key in sorted(person):
    print(key + ": " + str(person[key]))

Ausgabe:

Alter: 45
Nachname: Müller
Vorname: Herbert

Mit Hilfe der Methode items() lassen sich direkt Schlüssel/Wert-Paare für die Iteration bilden, was die Schreibweise erleichtert:

for key,value in sorted(person.items()):
    print(key + ": " + str(value))

(Ausgabe wie oben)

Dictionaries auf Inhalt überprüfen

Wird versucht, auf ein Schlüssel/Wert-Paar zuzugreifen, dass gar nicht existiert, so gibt das Programm einen KeyError zurück:

>>> person['Adresse']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Adresse'

Daher muss häufig in Programmen überprüft werden, ob zu einem bestimmten Schlüssel ein Wert hinterlegt wurde. Der Zugriff auf den Wert darf nur erfolgen, wenn dieser Wert existiert:

if 'Adresse' not in person:
    print('Keine Adresse erfasst')
else:
    print('Die Adresse lautet' + str(person['Adresse']))

Sofern in jedem Fall ein Wert ausgegeben werden soll (auch wenn zu dem übergebenen Schlüssel kein Eintrag existiert) kann die get()-Methode des Dictionaries verwendet werden. Dieser Methode kann ein default-Wert übergeben werden (hier: ‘N/A’ für ‘not available’/‘nicht verfügbar’)

>>> print("Die Adresse lautet "+person.get('Adresse', 'N/A'))
Die Adresse lautet N/A

Der selbe Aufruf führt bei gesetztem Wert zur Ausgabe des Wertes:

>>> person['Adresse'] = 'Musterstraße 12, 12345 Musterstadt'
>>> print("Die Adresse lautet "+person.get('Adresse', 'N/A'))
Die Adresse lautet Musterstraße 12, 12345 Musterstadt

Eine Überprüfung ist insbesondere auch erforderlich, wenn wir bei Schlüsseln Zählerwerte inkrementieren wollen, die bislang gar nicht gesetzt waren. Soll die Anzahl der Kinder erhöht werden bei einer Person, für die zu diesem Schlüssel bislang gar kein Wert gesetzt wurde, wird analog zu oben eine Fehlermeldung ausgegeben:

>>> person['Kinder'] +=1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Kinder'

Diese lässt sich verhindern, in dem über eine bedingte Anweisung zuvor festgestellt wird, ob der Schlüssel bekannt ist. Andernfalls wird ein Defaultwert/Startwert gesetzt:

if 'Kinder' not in person:
     person['Kinder'] = 0

Auch hierfür bietet ein Dictionary eine Methode, die genau diesen Defautlwert (hier 0) setzt:

person.setdefault('Dienstjahre', 0)

Weitere Methoden von Dictionary

Eine Reihe von Methodem der Klasse dict haben wir schon kennengelernt, Python bietet eine Reihe weiterer Methodden an. Die wichtigsten finden sich mit einer kurzen Erklärung in diesem UML-Klassendiagramm:

UML-Klassendiagramm für Dict

Eine Erklärung zu dict und deren Methoden und Attribute erhält man in der Python-Shell über:

>>> help(dict)

Wenn eine Liste der Methoden und Attribute reicht, dann bietet der dir()-Befehl die nötige Übersicht.

>>> dir(dict)

Um konkrete Hilfe zu einzelnen Methoden zu bekommen können diese auch direkt mit help() adressiert werden:

>>> help(dict.get)
Help on method_descriptor:

get(self, key, default=None, /)
    Return the value for key if key is in the dictionary, else default.

Type Annotations

Um Dictionaries und deren Elemente mit Kommentaren zu deren erwarteten Datentypen zu versehen, können Type-Annotations genutzt werden. Im Gegensatz zu den einfachen Annotations müssen die jedoch zuvor importiert werden:

from typing import Dict

Danach wird Dict (im Gegensatz zum Datentyp wird die Annotation in Großbuchstaben geschrieben!) und die Datentypen der Schlüssel/Wertpaare folgendermaßen angegeben:

artikelpreise: Dict[int, float]

konto: Dict[str, int] = {}
konto['iban'] = 12345

Rückgabewerte von Funktionen können entsprechend notiert werden:

def get_person(first_name: str, last_name: str) -> Dict[str, str]:
    """Wandle die übergebenen Werte in ein personen-dict um"""
    person = {"Vorname": first_name, "Nachname": last_name}
    return person

Die Type Annotation sind wie Kommentare zu verstehen, wir können sie jederzeit im Programm missachten, ohne dass der Interpreter dies moniert:

konto['bic'] = "DE1234"
artikelpreise["Hose"] = 89.99

Hinweis zur Nachnutzung als Open Educational Resource (OER)

Dieser Artikel und seine Texte, Bilder, Grafiken, Code und sonstiger Inhalt sind - sofern nicht anders angegeben - lizenziert unter CC BY 4.0. Nennung gemäß TULLU-Regel bitte wie folgt: “Objektsammlungen mit Dictionaries” von oer-informatik.de (H. Stein), Lizenz: CC BY 4.0. Der Artikel wurde unter https://oer-informatik.de/python_dictionary veröffentlicht, die Quelltexte sind in weiterverarbeitbarer Form verfügbar im Repository unter https://gitlab.com/oer-informatik/python-basics/erste-schritte-mit-python. Erstellt mit KI-Assistenz; von mir umfassend redaktionell überarbeitet, geprüft und freigegeben. Stand: 02.03.2024.

[Kommentare zum Artikel lesen, schreiben] / [Artikel teilen] / [gitlab-Issue zum Artikel schreiben]

Kommentare gerne per Mastodon, Verbesserungsvorschläge per gitlab issue (siehe oben). Beitrag teilen: