Dictionary Werte zusammenfassen.

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Marck
User
Beiträge: 2
Registriert: Montag 30. Dezember 2019, 12:30

Hallo alle zusammen,
also ich habe gerade erst angefangen mich mit Python zu beschäftigen und versuche mich nun in Materie einzufinden.

Nun bin ich dabei eine Beispielaufgabe durch zu arbeiten. Und hier bin ich auf ein Problem gestoßen was ich bisher nicht lösen konnte darum hoffe ich dass ihr mir helfen könnt.
Also nun mein Problem:

Ich habe ein Dictionary und eine Liste, nun möchte ich die Werte in einem neuen Dictionary zusammenfassen: (Falls es interessiert das Buch ist "Routineaufgaben mit python automatisieren")

Code: Alles auswählen

inv = {'gold coin': 42, 'rope': 1}
	   dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'gold coin', 'ruby']
Ich möchte gerne dass das ganze danach ca. so aussieht: neueDictionary = {'gold coin': 46, 'rope': 1, 'dagger': 1, 'ruby':1}

Ich habe versucht das ganze in listen umzuwandeln und dann zu addieren. Auch habe ich versucht dragonLoot in ein Dictionary um zu wandeln dragondict und dann die Werte (values) von 'gold coin' zu addieren.

inv = inv['gold coin'] + dragondict['gold coin']

Irgendwie glaube ich, dass ich mich verrannt habe.

Für ein paar Denkanstöße wäre ich euch dankbar.

Marc
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Möglicherweise gibt es eine Lösung mit itertools, die schlanker ist, aber ich würde zum besseren Verständnis das ganze zu Fuß machen.

Warum möchtest du das zu einem neuen Dict zusammenfassen? Wennd er Drache gelootet wird, dann verändert sich doch das bestehende Inventar, oder?
In dem Fall: Geh die einzelnen Elemente von dragonLoot durch. Prüfe ob das Element als Schlüssel im Inventar enthalten ist. Ist dem so, erhöhe dessen Wert um eins. Ist dem nicht so, lege einen neuen Schlüssel mit dem Wert 1 an.
Benutzeravatar
snafu
User
Beiträge: 6867
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das geht als Einzeiler, wenn man vorher den Counter importiert:

Code: Alles auswählen

from collections import Counter

inv = {'gold coin': 42, 'rope': 1}
dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'gold coin', 'ruby']
print(Counter(inv) + Counter(dragonLoot))
Benutzeravatar
snafu
User
Beiträge: 6867
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Falls man es dennoch zu Fuß machen möchte, wäre eine der Möglichkeiten das da:

Code: Alles auswählen

def get_total_counts(items, add_names):
    result = dict(items)
    for name in add_names:
        try:
            result[name] += 1
        except KeyError:
            result[name] = 1
    return result

inv = {'gold coin': 42, 'rope': 1}
dragon_loot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'gold coin', 'ruby']
print(get_total_counts(inv, dragon_loot))
Benutzeravatar
__blackjack__
User
Beiträge: 14051
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mit `dict.get()` kann man das immer noch lesbar ohne ``try``/``except`` schreiben:

Code: Alles auswählen

#!/usr/bin/env python3


def get_total_counts(items, names):
    result = dict(items)
    for name in names:
        result[name] = result.get(name, 0) + 1
    return result


def main():
    inventory = {"gold coin": 42, "rope": 1}
    dragon_loot = [
        "gold coin",
        "dagger",
        "gold coin",
        "gold coin",
        "gold coin",
        "ruby",
    ]
    print(get_total_counts(inventory, dragon_loot))


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Marck
User
Beiträge: 2
Registriert: Montag 30. Dezember 2019, 12:30

Hallo zusammen erstmal vielen Dank für eure Antworten, die haben mir seh geholfen. Ich sehe dass, ich da noch große Lücken in meinem Wissen habe ...
Für mich ist wohl die zweite Varriante von snafu am sinvollsten da ich erstmal genau begreifen muss was so geschieht, auch wenn natürlich die erste Varrainte schöner ist.
Ich werde mir aufjedenfall eure Lösungen nochmal genau zu gemüte führen bevor ich im Buch weitermache.

Marc
Benutzeravatar
snafu
User
Beiträge: 6867
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

__blackjack__ hat geschrieben: Montag 30. Dezember 2019, 20:04 Mit `dict.get()` kann man das immer noch lesbar ohne ``try``/``except`` schreiben:
Oder mit defaultdict:

Code: Alles auswählen

from collections import defaultdict

def get_total_counts(items, names):
    result = defaultdict(int, items)
    for name in names:
        result[name] += 1
    return result
Marck hat geschrieben: Montag 30. Dezember 2019, 22:35 Für mich ist wohl die zweite Varriante von snafu am sinvollsten da ich erstmal genau begreifen muss was so geschieht, auch wenn natürlich die erste Varrainte schöner ist.
Vielleicht hilft auch dies für den Anfang und dann kannst du dich allmählich vorarbeiten:

Code: Alles auswählen

def get_total_counts(items, names):
    result = dict(items)
    for name in names:
        if name in result:
            result[name] = result[name] + 1
        else:
            result[name] = 1
    return result
Benutzeravatar
DeaD_EyE
User
Beiträge: 1239
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Einfach das benutzen, was schon da ist und funktioniert:

Code: Alles auswählen

from collections import Counter

inv = {'gold coin': 42, 'rope': 1}
dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'gold coin', 'ruby']

new_inv = dict(Counter(inv) + Counter(dragonLoot))
Kannst auch Elemente wieder subtrahieren:

Code: Alles auswählen

Counter(new_inv) - Counter({'gold coin': 6})
Wenn ich die Aufgabe richtig verstanden habe, sollte das eine recht einfache Lösung sein.
Denke nur dran, dass du das Objekt inv ggf. updaten musst.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
DeaD_EyE
User
Beiträge: 1239
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Das mit dem Counter hat snafu ja bereits vorgeschlagen. Zu spät gesehen.
Jedenfalls kann man erkennen, dass die richtige Datenstruktur einem viel Denkarbeit abnehmen kann.
Ich kam auf die Idee mit dem Counter, weil ich gesehen habe, dass gezählt und addiert/subtrahiert werden muss.
Schön ist auch, dass man Sequenzen sowie Collections als Eingabe für den Counter verwenden kann,
sowie den Counter wieder in ein dictionary umwandeln kann.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten