Dictionaries gehören zu den zentralen Datentypen in Python. Wie ein Wörterbuch das Begriffe und deren Bedeutungen verknüpft, enthält das Python-Dictionary Elemente, die mit weiterer Information verknüpft sind. In Python spricht man bei Dictionaries ganz Allgemein von Key-Value oder auch Schlüssel-Wert Paaren. Solche Key-Value-Paare können beispielsweise sein:
- Codierungen in einem Fragebogen
- KFZ-Kennzeichen-Codes für Kreise
- HTTP-Statuscodes
- Windkraftanalagen und ihre Geopositionen
- Zeitstempel und erfasste Leistung von Maschinen
In diesem Beitrag wird der Datentyp Dictionary im Detail vorgestellt und zentrale Eigenschaften und Anwendungen beschrieben.
Inhalt¶
- Erstellen von Dictionaries
- Datenzugriffe
- Zuweisungen
- Iterieren über Dictionaries
- Dictionaries im Speicher
- Methoden von Dictionaries
- Zuweisungen
Erstellen von Dictionaries ¶
Um ein Python-Dictionary zu erzeugen, gibt es 2 Möglichkeiten: Die literale Initiierung und die funktionale Initiierung. Den Weg der literalen Initiierung wählt man in der Regel, wenn auf statische Weise (bspw. per Handeingabe in der Console) kleine Objekte mit wenigen Schlüssel-Wert-Paaren erzeugt werden. In Programmen werden Dictionaries eher auf dynamische (generische) Weise erzeugt. Dafür benötigt man den funktionalen Weg.
Die Keys in einem Dictionary müssen die Bedingung eines Immutable Objects erfüllen. D.h. der Key kann z.B. ein String, Int, Tupel oder Float sein. Das Objekt eines Dictionary-Werts kann jeden Typs sein.
1. Literale Initiierung¶
Die folgende Abbildung zeigt das syntaktische Schema des Dictionary-Literals:
Hier erzeugen wir uns ein Beispieldictionary mit 3 Einträgen zu HTTP-Statuscodes.
myDict = {200:'OK', 404:'Not Found', 502:'Bad Gateway'}
>>>{200: 'OK', 404: 'Not Found', 502: 'Bad Gateway'}
2. Funktionale Initiierung¶
Mit der Funktion dict werden Dictionaries ebenfalls erzeugt. Gegenüber der literalen Initiierung weist die Funktion allerdings einige syntaktische Tücken auf. Werden ihr Key-Value Zuordnungen auf diese Weise übergeben:
dict(A=1,B=2,C=3)
>>>{'A': 1, 'B': 2, 'C': 3}
müssen die Keys den Python Identifier-Regeln entsprechen. D.h. sie müssen mit einem Unterstrich oder einem Buchstaben beginnen. Die Funktion übersetzt die Keys intern schließlich in Strings.
Um über den Funktionsaufruf ein Dictionary zu erstellen, welches einen anderen Typ von Keys enthält, müssen der Funktion Key-Value-Paare als Tupel in Listenform übergeben werden.
dict([(1,'111'), (2,'222'), (3,'333'),])
>>>{1: '111', 2: '222', 3: '333'}
Die dict-Funktion ist insbesondere dann wichtig, wenn aus Listen ein Dictionary erzeugt werden soll.
code = [1,2,3,4,5]
item = ['Stimme voll zu', 'Stimme eher zu', 'Unentschlossen', 'Stimme eher nicht zu', 'Stimme überhaupt nicht zu']
zipped = zip(code, item)
print(dict(zipped))
>>>{1: 'Stimme voll zu', 2: 'Stimme eher zu', 3: 'Unentschlossen', 4: 'Stimme eher nicht zu', 5: 'Stimme überhaupt nicht zu'}
Datenzugriffe ¶
Normalerweise erfolgt der Zugriff auf das Dictionary über die Schlüssel. Innerhalb von eckigen Klammern (über die in Python üblicherweise Positionen indiziert werden) wird dieser an das Dictionary gehangen und dient dann als Filter. Die Rückgabe eines solchen Ausdrucks ist der zum Schlüssel gehörige Wert.
Natürlich gibt es auch die Möglichkeit über einen Wertefilter die zuhörigen Keys aus dem Dictionary zu erfragen. Diese Variante wird im Beispielcode ebenfalls gezeigt:
myDict = {200:'OK', 404:'Not Found', 502:'Bad Gateway'}
# --- Zugriff auf Werte über Key
# Einzelnes Item
myDict[200]
>>> OK
# Mehrere Items
items = [200,502]
values = [myDict[i] for i in items]
print(values)
>>> ['OK', 'Bad Gateway']
# --- Zugriff auf Key über Werte
values = ["Not Found", "OK"]
keys = [k for k, v in myDict.items() if v in values]
print(keys)
>>> [200, 404]
Zuweisungen ¶
Zuweisungen erfolgen üblicherweise über den Zugriff auf ein Key-Element und ändern den entsprechenden Wert. In dem Beispielcode wird der Wert für den Key 200 geändert. Änderungen an den Keys können natürlich ebenfalls vorgenommen werden. Dafür bietet sich die Method pop an (siehe unten: Methoden von Dictionaries).
# --- Wertzuweisung
myDict = {200:'OK', 404:'Not Found', 502:'Bad Gateway'}
myDict[200] = '__OK__'
print(myDict)
>>> {200: '__OK__', 404: 'Not Found', 502: 'Bad Gateway'}
item = {200:"__NOT OK__"}
myDict.update(item)
print(myDict)
>>> {200: '__NOT OK__', 404: 'Not Found', 502: 'Bad Gateway'}
# --- Keyzuweisung
myDict[2000] = myDict.pop(200)
print(myDict)
>>> {2000: '__NOT OK__', 404: 'Not Found', 502: 'Bad Gateway'}
Iterieren über Dictionaries ¶
Iterationen über Dictionaries erfolgen im einfachsten Fall über die Keys.
myDict = {200:'OK', 404:'Not Found', 502:'Bad Gateway'}
for i in myDict:
print(i)
>>> 200
>>> 404
>>> 502
Eine häufige Anwendung ist es jedoch, innerhalb der Iterationen neben dem Zugriff auf den Schlüssel auch den Wert anzusprechen. Dies gelingt mit der Methode items. Sie erzeugt aus dem Dictionary eine Liste mit Tupeln, über die iteriert wird.
myDict = {200:'OK', 404:'Not Found', 502:'Bad Gateway'}
# Zur Veranschaulichung wird hier die Ausgabe von items() angezeigt. Über dieses Objekt wird in der unten
# aufgeführten Schleife iteriert.
print(myDict.items())
>>> dict_items([(200, 'OK'), (404, 'Not Found'), (502, 'Bad Gateway')])
for key, value in myDict.items():
print(key, value)
>>> 200 OK
>>> 404 Not Found
>>> 502 Bad Gateway
Wie für den Datentyp Liste existiert für Dictionaries eine Kurzschreibweise von Schleifen: Die Dict-Comprehensions. Im ersten Codebeispiel werden mit Hilfe der Dict-Comprehension die Keys in einem String modifiziert. Das zweite Beispiel erzeugt aus 2 Listen ein Dicitonary.
myDict = {200:'OK', 404:'Not Found', 502:'Bad Gateway'}
{str(k) + '__SUFFIX': v for k, v in myDict.items()}
>>> {'200__SUFFIX': 'OK', '404__SUFFIX': 'Not Found', '502__SUFFIX': 'Bad Gateway'}
keys = [200, 404, 502]
values = ['OK', 'Not Found', 'Bad Gateway']
{v: values[i] for i, v in enumerate(keys)}
>>> {200: 'OK', 404: 'Not Found', 502: 'Bad Gateway'}
Dictionaries im Speicher ¶
Dictionaries ähneln in ihrer Python-Implementierung dem Typ Liste. Wie auch Listen sind Dictionaries Mutable Objects, d.h. auch sie verändern ihren physikalischen Speicherort nicht, wenn Änderungen an ihnen vorgenommen werden. Und wie Listen auch, enthalten Dictionaries nicht die Objekte selbst, sondern lediglich deren Referenzen. Im Gegensatz zu Listen sind Dictionaries allerdings nicht sortiert. Ihre Werte sind lediglich über die entsprechenden Schlüssel ansprechbar, nicht aber über eine Position.
Aus dem Beispielcode lassen sich die oben genannten Eigenschaften zeigen. Sowohl das leere Dictionary myDict als auch das mit 5 Key-Value-Paaren befüllte Dictionary myDict haben eine Größe von 288 Bytes. Der Speicherort hat sich durch das Befüllen nicht geändert. Außerdem sehen wir, dass die Größe aller Values mit 297 Bytes die Größe der Liste überschreitet und es somit ausgeschlossen ist, dass das Dictionary selbst die Objekte enthält.
import sys
myDict = {} # Erstelle leeres Dictionary
print(id(myDict))
>>>2239975926472 # Physikalischer Speicherort von myDict
sys.getsizeof(myDict)
>>>288 # Größe von myDict
# Befüllen von myDict
myDict2 = {200:'OK', 404:'Not Found', 502:'Bad Gateway', 403:'Forbidden', 500:'Internal Server Error'}
myDict.update(myDict2)
print(id(myDict))
>>>2239975926472
print(sys.getsizeof(myDict))
>>>288
# --- Summiere die Größe aller im Dictionary enthaltenen Werte
total_size_values = 0
for k, v in myDict.items():
total_size_values += sys.getsizeof(v)
print(total_size_values)
>>>297
Unser Dictionary enthält im Moment 5 Key-Value-Paare und hat damit den Speicherpuffer erschöpft. Wir sehen dies, indem wir ein weiteres Key-Value-Paar an das Dictionary anhängen und erneut die Größe des Dictionaries abfragen. Diese hat sich von 280 Bytes auf 480 Bytes erhöht:
new_item = {202: "Accepted"}
myDict.update(new_item)
print(sys.getsizeof(myDict))
>>> 480
Folgendes Schaubild zeigt noch einmal das Speichermanagement von Dictionaries in schematischer Form:
Methoden von Dictionaries ¶
Methode |
Beispiel |
Funktionsweise |
---|---|---|
clear | myDict = {200:’OK‘, 404:’Not Found‘, 502:’Bad Gateway‘}
myDict.clear() print(myDict) |
Entfernt alle Schlüssel-Wert-Paare aus dem Dictionary. |
copy | myDict = {200:’OK‘, 404:’Not Found‘, 502:’Bad Gateway‘}
y = myDict y = myDict.copy() |
Erstellt eine Kopie des Dictionaries im Speicher. |
fromkeys | myDict = {} myDict = myDict.fromkeys((‚A‘,’B‘,’C‘), 0) print(myDict) >>>{‚A‘: 0, ‚B‘: 0, ‚C‘: 0} dict.fromkeys([1,2,3]) |
Erstellt ein Dictionary aus einem Tupel oder einer Liste von Immutable-Objects. Jedem Schlüssel wird ein Default-Wert zugewiesen. Da es sich um eine Klassenmethode handelt, ist auch die Eingabe dict.fromkeys() möglich. |
get | myDict = {200:’OK‘, 404:’Not Found‘, 502:’Bad Gateway‘}
print(myDict.get(200)) |
Holt den Wert über die Eingabe des Schlüssels. |
items | myDict = {200:’OK‘, 404:’Not Found‘, 502:’Bad Gateway‘}
myDict.items() |
Wandelt das Dictionary in eine Liste von Tupeln um. Jedes Tupel entspricht einem Schlüssel-Wert-Paar. Die Methode wird zum iterieren über Dictionaries verwendet. |
keys | myDict = {200:’OK‘, 404:’Not Found‘, 502:’Bad Gateway‘}
myDict.keys() |
Gibt die Keys des Dictionaries zurück. |
pop | myDict = {200:’OK‘, 404:’Not Found‘, 502:’Bad Gateway‘}
myDict.pop(200) |
Entfernt ein Schlüssel-Wert-Paar aus dem Dictionary. |
popitem | myDict = {200:’OK‘, 404:’Not Found‘, 502:’Bad Gateway‘}
myDict.popitem() |
Entfernt ein zufälliges Schlüssel-Wert-Paar aus dem Dictionary. |
setdefault | myDict = {200:’OK‘, 404:’Not Found‘, 502:’Bad Gateway‘}
print(myDict.setdefault(200)) print(myDict.setdefault(403,’Forbidden‘)) print(myDict.setdefault(200,’TEST‘)) |
Holt den Wert über die Eingabe des Schlüssels (vergleichbar mit der Methode get). Nur wenn der Schlüssel nicht im Dictionary vorhanden ist, wird ein entsprechendes Schlüssel-Wert-Paar im Dictionary erstellt. |
update | myDict = {200:’OK‘, 404:’Not Found‘, 502:’Bad Gateway‘}
myDict2= {100:’Continue‘, 400:’Bad Request‘} myDict3 = {200:’ok‘} |
Hängt ein Dictionary an ein anderes Dictionary an. Bei Schlüssel-Duplikaten wird der Wert mit dem angehangenen Dictionary überschrieben. |
values | myDict = {200:’OK‘, 404:’Not Found‘, 502:’Bad Gateway‘}
myDict.values() |
Gibt alle Werte des Dictionaries aus. |
Weitere Funktionen auf Dictionaries ¶
myDict = {200:'OK', 404:'Not Found', 502:'Bad Gateway'}
len() – Die Länge des Dictionaries ermitteln
len(myDict)
del – Key-Value-Paare aus dem Dictionary löschen
del myDict[404]
print(myDict)
>>>{200: 'OK', 502: 'Bad Gateway'}
in-Operator – Prüft, ob ein Schlüssel im Dictionary enthalten ist
404 in myDict
>>>True
Arithmetische Operationen auf Dictionaries
myDict = {'A':100, 'B':200, 'C':300}
max(myDict.values()) # Wird die Methode values nicht angewendet, wird die Funktion auf die Keys angewendet.
min(myDict.values())
# Das Modul statistics verfügt über zahlreiche Funktionen aus der Deskriptiven Statistik
from statistics import mean, median, stdev, variance
mean(myDict.values())
median(myDict.values())
stdev(myDict.values())
variance(myDict.values())