Python ERWEITERTE Datentypen - Was ist DefaultDict?

Python hat mit Listen, Sets, Tupel und Dictionaries eine Reihe nützlicher Datenstrukturen direkt mit dabei.
Aber wusstest du, dass du auch noch Hilfe dabei kommst die Typen so effizient wie möglich zu nutzen?
In dieser kleinen Serie möchte ich dir zeigen welche das sind!

Heute geht es um das Dictionary.
Über einen Schlüssel auf Werte zugreifen zu können ist nicht nur schnell sondern auch angenehm!
Einmal nicht aufgepasst gibt es sofort einen KeyError, weil der Schlüssel nicht gefunden werden konnte. 
Also: Prüfen ob der Schlüssel vorhanden ist und dann erst abfragen.

Aber was, wenn wir das vermeiden könnten?
Abfragen einfach ohne vorherige Prüfung direkt durchführen und trotzdem keinen Fehler bekommen?

Inhalt:
    Add a header to begin generating the table of contents
    Python Logo

    Mit dem collections Modul bekommst du mehrere Klassen, die dir dabei helfen sollen die verschienen Typen in Python so effizient wie möglich zu nutzen.

    Als Beispiel dient eine ToDo Liste.
    Aufgaben können zur Liste hinzugefügt oder auch wieder entfernt werden.

    Das typische Dictionary...

    Kurz zur Erinnerung:
    Ein Dictionary ist immer ein Schlüssel-Werte Paar.
    Über den Schlüssel kann der Wert identifiziert und zurück gegeben werden.

    Also erstmal ein Dictionary erzeugen:

    data = dict()
    data['Kurzbeschreibung'] = 'Geschirrspüler ausräumen'
    data['Kategorie'] = 'Küche'
    data['Priorität'] = 'Wichtig' 

    Wenn du jetzt wissen möchtest wie die Kurzbeschreibung lautet, kannst du sie einfach abfragen:

    data['Kurzbeschreibung'] 

    Schon wird dir ‘Geschirrspüler ausräumen’ als Antwort geliefert.

    Das Problem mit den Keys

    Das funktioniert super, so lange du den richtigen Key benutzt. 
    Solltest du aber einmal einen Key benutzen, den es nicht gibt, bekommst du schnell Probleme:

    data['Status']
    
    ---------------------------------------------------------------------------
    KeyError                                  Traceback (most recent call last)
    <ipython-input-17-b4811a849e5e> in <module>()
          7 }
          8 
    ----> 9 data['Status']
    
    KeyError: 'Status'
     

    Es kommt zu einem KeyError.

    Deswegen musst du immer prüfen, ob es einen Key gibt, bevor du das Dictionary danach fragst:

    if 'Status' in data.keys():
      data['Status']
    else:
      print('Key nicht gefunden!') 

    Ganz schön umständlich oder?

    Erzeugen mit Fallback

    Im collections Modul findest du eine Funktion defaultdict().
    Der kannst du einen Parameter übergeben.
    Und zwar eine Funktion.
    Die Funktion definiert einen Platzhalter der dann zurück gegeben wird, wenn der Schlüssel nicht gefunden wurde.

    Keine Sorge, eigentlich ganz einfach:

    data = defaultdict(str)
    data['Kurzbeschreibung'] = 'Geschirrspüler ausräumen'
    data['Kategorie'] = 'Küche'
    data['Priorität'] = 'Wichtig'
     
    data['Status'] 

    Eine kleine Änderung an unserem Beispiel und schon gibt es keinen Fehler mehr sondern einfach einen Leerstring. 
    Statt das Dictionary mit der dict() Funktion zu erzeugen hast du mit defaultdict() festgelegt, dass als default – also wenn der Schlüssel nicht gefunden wurde – ein String zurück gegeben werden soll.

    Genauso könntest du hier list oder dict oder sonst etwas verwenden.

    Ein Praxisbeispiel

    Stell dir vor, du möchtest deine Aufgabenliste nach Priorität gruppieren.
    Du willst also wissen, welche Aufgaben sind Wichtig, welche Sehr wichtig und so weiter.

    Mit einem regulären Dictionary sieht das so aus:

    aufgaben = [('Geschirrspüler ausräumen', 'Küche', 'Wichtig'),
                ('Schreibtisch aufräumen', 'Büro', 'Sehr wichtig'),
                ('Couch säubern', 'Wohnzimmer', 'Wichtig')]
     
    by_priority = {}
    for description, room, priority in aufgaben:
      if priority not in by_priority:
        by_priority[priority] = []
      by_priority[priority].append(description)
     
    print(by_priority) 

    Du musst also immer erst prüfen, ob es zu der Priorität bereits einen Eintrag gibt.
    Wenn nicht, dann erzeugst du eine Liste und erst im Anschluss kannst du deinen Wert hinzufügen.

    Mit dem defaultdict() sieht das ganze so aus:

    aufgaben = [('Geschirrspüler ausräumen', 'Küche', 'Wichtig'),
                ('Schreibtisch aufräumen', 'Büro', 'Sehr wichtig'),
                ('Couch säubern', 'Wohnzimmer', 'Wichtig')]
     
    by_priority = defaultdict(list)
    for description, room, priority in aufgaben:
      by_priority[priority].append(description)
     
    print(by_priority) 

    Eine kleine Änderung, aber schon 2 Zeilen Code eingespart und alles übersichtlicher geschaffen.

    Zusammenfassung:

    Kurz zusammengefasst: Mit dem defaultdict() vermeidest du unerwartete KeyError.
    Das heißt nicht nur weniger Schreibarbeit, weil du keine unnötigen Prüfungen mehr brauchst, sondern demnach auch bessere Lesbarkeit.

    Weniger Code ist natürlich nicht nur bessere Lesbarkeit sondern auch bessere Wartbarkeit.

    Probier es aus und sag mir deine Meinung zu defaultdict()!

    Beitragsbild - collections - Counter
    mehr lesen »
    Beitragsbild - Was ist die Zukunft von Big Data
    mehr lesen »
    Beitragsbild - Collections - NamedTuple
    mehr lesen »

    Kommentar verfassen

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

    Scroll to Top