Collections defaultdict

  • Ich habe ein kurzes Testprogramm zum "collections" verstehen:


    out:

    %Run collections_example.py
    dict_values(['red', 'yellow', 'green', 'White', 'red'])
    dict_keys([5, 6, 13, 19, 26])
    [(1, 'orange'), (2, 'pink'), (16, 'vioolet')]
    before {5: 'red', 6: 'yellow', 13: 'green', 19: 'White', 26: 'red'}
    after {5: 'red', 6: 'yellow', 13: 'green', 19: 'White', 26: 'red', 1: 'orange', 2: 'pink', 16: 'vioolet'}
    Counter({'o': 2, 'v': 1, 'i': 1, 'l': 1, 'e': 1, 't': 1})

    close

    after result o.k., aber kein log_missing

    out:

    dict_values(['red', 'yellow', 'green', 'White', 'red'])
    dict_keys([5, 6, 13, 19, 26])
    [(1, 'orange'), (2, 'pink'), (16, 'vioolet')]
    before {5: 'red', 6: 'yellow', 13: 'green', 19: 'White', 26: 'red'}
    Key added
    Key added
    Key added
    after {5: 'red', 6: 'yellow', 13: 'green', 19: 'White', 26: 'red', 1: 0, 2: 0, 16: 0}
    Counter({'o': 2, 'v': 1, 'i': 1, 'l': 1, 'e': 1, 't': 1})

    close

    after nicht o.k. aber log_missing

    Was mache ich hier falsch ??

    Dank und Gruß DP

  • Die Frage ist ja was willst Du da erreichen? Warum ist "after" nicht okay, denn das ist das was der Code sagt was passieren soll.

    Als Fehler würde ich im ersten Code ansehen, dass da ein Default-Wert von 0 angegeben wird, für ein Wörterbuch in dem die Werte aber gar keine Zahlen sondern Zeichenketten sind. Python erlaubt das, aber es ist verwirrend und meistens falsch.

    Und im zweiten Code würde ich als Fehler ansehen, dass da in der Schleife in Zeile 24 ein Ausdruck steht dessen Ergebnis nirgends verwendet wird. Das ist eine sehr verschleierte Art als Seiteneffekt das Wörterbuch zu verändern.

    Bei log_missing() ist auch die Ausgabe das da ein Schlüssel hinzugefügt wurde ein bisschen unvollständig, denn da werden ja Schlüssel und Wert hinzugefügt, und durch die Funktion wird der Wert festgelegt. Das wird auch klarer wenn die Funktion einen etwas passenderen Namen hätte: create_missing_value().

    Code
    B*
         PC  IRQ  SR AC XR YR SP
    .;  0401 E455 32 04 5E 00 F8
    .█
  • Das Ziel sollte sein, dass das Dictonary um die zusätzlichen WErte ergänzt wird, was in Version 1 korrekt gemacht wird.Jedoch fand ich die Funktion log_missing() und die zugehörige Ausgabe gut, aber das haut irgendwie nicht richtig hin ??!!

    (ist übrigens ein leicht abgewandeltes Zitat aus Brett Slatkin Effective Python Item48 bei dem allerdings die "values" Werte sind, daher mach return 0 wahrscheinlich eher Sinn )

    Dank und Gruß DP

  • devil P Im ersten Beispiel wird das defaultdict ja gar nicht benutzt, also der Umstand, das es so eines ist. Das wird ja nichts gemacht was nicht auch ein normales dict kann.

    Es ist etwas aufwendiger ausgedrückt als es sein müsste, denn die Schleife braucht man nicht selbst schreiben sozusagen:

    Beim zweiten Beispiel verstehe ich nicht wie Du das beim abfragen nach dem pin erwartet hast, das auf magische Weise der dazugehörende Wert aus einem ganz anderen Wörterbuch in das abgefragte Wörterbuch eingetragen werden sollte. Der Wert hinter pin ist ja einfach nur eine Zahl die gar keine Ahnung davon hat über welche Namen oder Strukturen man auf sie zugreifen kann.

    Ein defaultdict liefert bei Abfrage eines Schlüssels den dazugehörigen Wert. Sollte der Schlüssel nicht enthalten sein, dann wird kein KeyError ausgelöst, sondern die Fabrikfunktion aufgerufen, die man da übergeben hatte, um einen Wert zu erstellen, den unter dem Schlüssel einzutragen, und dann für die Abfrage zurück zu liefern.

    Der Counter mit dem letzten Farbnamen macht ja auch nicht wirklich Sinn.

    Code
    B*
         PC  IRQ  SR AC XR YR SP
    .;  0401 E455 32 04 5E 00 F8
    .█
  • __blackjack__ , Dennis89 zunächst vielen Dank für Eure Kommentare, das Thema ist zugegebener Maßen etwas akademisch, deshalb, bitte wenn es Euch zu dumm ist ...

    ich habe jetzt defaultdict besser verstanden, aber wenn ich dies Program laufen lasse:

    erhalte ich:

    before {5: 'red', 6: 'yellow', 13: 'green', 19: 'White', 26: 'red'}
    after {5: 'red', 6: 'yellow', 13: 'green', 19: 'White', 26: 'red', 1: 'orange', 2: 'pink', 16: 'violet'}

    before {'green': 12, 'blue': 3}
    Key added
    Key added
    after {'green': 12, 'blue': 20, 'red': 5, 'orange': 9}

    close

    warum ruft er im 2. Falle log_missing auf und im ersten nicht? (es hängt irgendwie mit += zusammen ???

    wie gesagt: habe mich ein wenig festgebissen :cursing:und würde es gern verstehen :)

    1000 Dank und gruß DP

  • devil P Die Fabrikfunktion wird aufgerufen wenn ein Schlüssel abgefragt wird der nicht enthalten ist. Im ersten Fall werden gar keine Schlüssel abgefragt, also wird da auch nie die Fabrikfunktion aufgerufen.

    Im zweiten Fall werden Schlüssel abgefragt, denn += nimmt ja den alten Wert und addiert da etwas drauf, und trägt dann das Ergebnis ein. mapping[key] += value ist ja letztlich (normalerweise) das gleiche wie mapping[key] = mapping[key] + value. Mit einem normalen dict würde das einen KeyError geben wenn der Schlüssel vorher nicht schon vorhanden ist:

    Ist ja logisch denn zu was sollte denn da 23 addiert werden, wenn es den Schlüssel nicht gibt und damit auch keinen Wert zu dem man etwas addieren könnte.

    Code
    B*
         PC  IRQ  SR AC XR YR SP
    .;  0401 E455 32 04 5E 00 F8
    .█
  • warum ruft er im 2. Falle log_missing auf und im ersten nicht? (es hängt irgendwie mit += zusammen ???

    Ja. Weißt du, was `+=` bedeutet?

    Der Unterschied ist jedenfalls, dass im 1. Beispiel ausschließlich Schlüssel angelegt werden, im zweiten ab _nur_ auf Schlüssel zugegriffen wird. Und wenn die nicht existent sind, wird der halt angelegt.

    Gruß, noisefloor

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!