Seite 1 von 1

Summe aus 2 Dictionaries

Verfasst: Dienstag 10. November 2020, 11:24
von elguapo
Hallo erstmal,
ich bin hier neu und auch in python ein Neuling. Ich habe einige Daten in Python zusammengefügt und berechnet. Nun stosse ich aber an meine laienhaften Grenzen. Ich habe u.a. ein Dictionary mit key(s) und dann als value eine Liste. In dieser ist die Niederlassung der Pkws vermerkt. Ich möchte nun über ein 2 Dictionary eine Summe der Autos ausgeben die in Niederlassung 1 und 2 sind. Dabei interessiert mich die Marke nicht, sondern nur die Niederlassung. Der zuberechnende Wert in der Liste wäre die Summe aus Eintrag [-2], also die Zahlen und die Referenz [-1] also die Niederlassung.

auto = {
"bmw": ["blau", "automatik", 5, "nl_01"],
"audi": ["rot", "manuell", 4, "nl_02"],
"smart": ["blau", "automatik", 2, "nl_01"],
"audi": ["blau", "manuell", 5, "nl_01"],
"opel": ["blau", "automatik", 1, "nl_02"],
}

niederlassung = {
"nl_01": "Bremen",
"nl_02": "Hamburg",
}

Ergebnis soll sein:
Bremen = 12
Hamburg = 5

Vielen Dank schon mal.

Re: Summe aus 2 Dictionaries

Verfasst: Dienstag 10. November 2020, 12:28
von __blackjack__
@elguapo: Das Ergebnis ist eine Ausgabe nehme ich mal an. Was ist denn jetzt das konkrete Problem? Du hast Werte/Datenstrukturen gegeben, und eine Ausgabe zu der Du hin willst. Jetzt musst Du, ähnlich wie in der Mathematik, einen Weg finden von dem was gegeben ist, zu dem was gesucht ist zu kommen. Über gegebenfalls über Zwischenergebnisse. Wie sähe denn beispielsweise eine Datenstruktur aus die das gesuchte Ergebnis darstellen würde? Die nächste Frage ist dann wie man die aus den gegebenen Daten aufbauen könnte.

Tipp für Datentyp: `collections.defaultdict`. Dann spart man sich Code den man für ein `dict` sonst selbst schreiben müsste. Wobei das mit der `get()`-Methode, wenn man sich da mal alle Argumente anschaut, auch nicht wirklich kompliziert ist.

Re: Summe aus 2 Dictionaries

Verfasst: Dienstag 10. November 2020, 12:38
von Jankie
Das obere Dictionary ist falsch, so kann man die Aufgabe nicht lösen. Keys sollten einzigartig sein, zwei mal der selbe Key in einem Dict geht nicht.


Ich würde da so vorgehen:

bremen auf 0 setzen
hamburg auf 0 setzen
Eine Schleife über niederlassung_key, niederlassung_value von niederlassung.
Eine Schleife über auto_key, auto_value von auto.
Wenn niederlassung_value gleich "Bremen" ist und der dritte Wert von auto_value gleich dem niederlassung_key ist, wird der zweite Wert von auto_value auf bremen addiert.
Wenn niederlassung_value gleich "Hamburg" ist un der dritte Wert von auto_value gleich dem niederlassung_key ist, wird der zweite Wert von auto_value auf hamburg addiert.
Dann am Ende werden beide Werte (hamburg, bremen) ausgegeben.

Re: Summe aus 2 Dictionaries

Verfasst: Dienstag 10. November 2020, 14:01
von elguapo
@jankie:
du hast vollkommen recht: 2x audi geht nicht, muss halt ford sein. grundsätzlich komme ich aber nicht weiter.

@__blackjack__: ersteinmal danke für deine antwort.
das obige ergebnis ist was rauskommen soll. ich denke es geht mit einer funktion.
bsp.:

def niederlassung(auto: dict, niederlassung: dict):
result_nl = {}
for key in niederlassung:
if key in auto.keys():
niederlassung[key] = sum(auto[-1]) """==> das ist wohl falsch; ich möchte eine Summe pro Niederlassung, dh. Summe auf letzten Wert der Liste im Dictionary auto über den Referenzwert nl_01 und nl_02 (letzter Eintrag in Dict auto) und diesen dann übergeben""""
result_nl = niederlassung
return result_nl

"""Das Ergebnis wäre dann"""
result_nl = {
nl_01: 12,
nl_02: 5,
}

Danke elguapo

Re: Summe aus 2 Dictionaries

Verfasst: Dienstag 10. November 2020, 15:02
von __blackjack__
@elguapo: Lass mal diese unsinnigen Typannotationen weg oder mach sie wirklich ordentlich und vollständig. Und was verwendest Du zum prüfen der Typannotationen? Wenn man die nämlich nicht prüft ist das sogar ein Stück weit gefährlich die zu machen, denn die machen ja ein deutlich stärkeres Versprechen als Kommentare oder Dokumentation. Der Leser verlässt sich darauf, das die Angaben dort automatisiert statisch überprüft wurden.

Literale Zeichenketten sind keine Kommentare. Das Kommentarzeichen ist #, nichts anderes.

Und ja es ist falsch eine einfache Zuweisung zu machen wenn man eigentlich etwas aufsummieren will. Der Operator dafür ist ``+``.

`key` ist eine Niederlassungs-ID. Die ist niemals in den Schlüsseln von `auto`, denn das sind ja Automarken.

Am Anfang der Funktion wird `result_nl` als leeres Wörterbuch definiert. Das wird dann aber nirgends verwendet. Sollte es aber wohl, denn da soll ja am Ende das Ergebnis drin stehen.

Wohingegen es überhaupt keine gute Idee ist eines der Argumente zu verändern, und dann auch noch andere Informationen dort zu speichern als das ursprünglich enthalten waren. Du würdest bei `niederlassung` ja die Werte überschreiben, und wie soll man dann von der Niederlassungs-ID zum Namen der Stadt kommen wenn die Städtenamen durch Zahlen ersetzt wurden? Funktionen sollten in der Regel ihre Argumente nicht verändern sondern neue Werte/Datenstrukturen erstellen und als Rückgabewert liefern.

Namen: `auto` und `niederlassung` sind schlechte weil unpassende Namen. `auto` beschreibt nicht *ein* Auto. Um Grunde nicht einmal mehrere Autos, sondern den Warenbestand pro Automarke für alle Niederlassungen. Und letztendlich haben wir durch die Doppelung beim "audi" auch gesehen, das die Datenstruktur nicht funktioniert. Man kann damit nicht die gleiche Automarke in mehr als einer Niederlassung haben, oder mit unterschiedlichen Werten für die Gangschaltung in der gleichen Niederlassung. Mit dieser Datenstruktur lassen sich die realen Daten überhaupt nicht abbilden.

`niederlassung` beschreibt keine Niederlassung, sondern ist eine Abbildung von Niederlassungs-ID auf einen Städte- oder Ländernamen. Kann man bei den beiden Beispielwerten nicht genauer erkennen, denn beides sind ja gleichzeitig Stadt und Bundesland.

`result_nl` ist ein schlechter Name weil er eine kryptische Abkürzung enthält.

Und `niederlassung()` ist ein schlechter Name für eine Funktion weil der keine Tätigkeit beschreibt. Funktions- und Methodennamen beschreiben üblicherweise die Tätigkeit die von dem Code durchgeführt wird, um sie von eher passiven Werten unterscheiden zu können. Der Name `niederlassung` wird hier auch mehrfach belegt, einmal als Datenstruktur und dann als Funktion, und auch noch als Argumentname in dieser Funktion. Das ist sehr verwirrend.

Re: Summe aus 2 Dictionaries

Verfasst: Dienstag 10. November 2020, 15:17
von Jankie
Wie du da grundsätzlich vorgehen kannst habe ich doch schon geschreiben. Versuch das doch mal umzusetzen. Wenn du das dann hast kannst du das auch in eine Funktion packen oder die Ergebnisausgabe als Dictionary versuchen.

Oder du versuchst es wie von __blackjack__ beschrieben.

Re: Summe aus 2 Dictionaries

Verfasst: Dienstag 10. November 2020, 15:27
von Sirius3
@Jankie: warum sollte man zwei Schleifen schreiben? Dafür hast Du doch ein Wörterbuch über die Niederlassungen.

Re: Summe aus 2 Dictionaries

Verfasst: Mittwoch 11. November 2020, 08:05
von Jankie
Stimmt, hab das ganze noch mal überarbeitet.

Code: Alles auswählen

from collections import defaultdict

CARBRAND_TO_STOCK_CARS = {
    "bmw": ["blau", "automatik", 5, "nl_01"],
    "benz": ["rot", "manuell", 4, "nl_02"],
    "smart": ["blau", "automatik", 2, "nl_01"],
    "audi": ["blau", "manuell", 5, "nl_01"],
    "opel": ["blau", "automatik", 1, "nl_02"],
}

BRANCH_ID_TO_CITYNAME = {
    "nl_01": "Bremen",
    "nl_02": "Hamburg",
}

def main():
    result = defaultdict(int)
    for carbrand_value in CARBRAND_TO_STOCK_CARS.values():
        result[BRANCH_ID_TO_CITYNAME.get(carbrand_value[3])] += carbrand_value[2]
    print(result)

if __name__ == "__main__":
    main()

Re: Summe aus 2 Dictionaries

Verfasst: Mittwoch 11. November 2020, 08:24
von Sirius3
@Jankie: `carbrand_value` solltest Du gleich in 4 Variablen entpacken.

Re: Summe aus 2 Dictionaries

Verfasst: Mittwoch 11. November 2020, 08:42
von Jankie
Damit die Lesbarkeit erhöht wird?

Würde man dann eher alle entpacken und zwei einfach nicht verwenden, also so:

Code: Alles auswählen

def main():
    result = defaultdict(int)
    for carbrand_value in CARBRAND_TO_STOCK_CARS.values():
        car_color, transmission_type, number_of_cars, car_branch = carbrand_value
        result[BRANCH_ID_TO_CITYNAME.get(car_branch)] += number_of_cars
    print(result)
oder würde man die Liste slicen und nur die letzten zwei Elemente verwenden?

Code: Alles auswählen

def main():
    result = defaultdict(int)
    for carbrand_value in CARBRAND_TO_STOCK_CARS.values():
        number_of_cars, car_branch = carbrand_value[-2:]
        result[BRANCH_ID_TO_CITYNAME.get(car_branch)] += number_of_cars
    print(result)

Re: Summe aus 2 Dictionaries

Verfasst: Mittwoch 11. November 2020, 09:47
von __deets__
Man entpackt ungebrauchte Elemente in den _

Code: Alles auswählen

for a, b, _, _ in ...

Re: Summe aus 2 Dictionaries

Verfasst: Mittwoch 11. November 2020, 10:22
von Sirius3
Man entpackt schon im for:

Code: Alles auswählen

def main():
    result = defaultdict(int)
    for _, _, number_of_cars, car_branch in CARBRAND_TO_STOCK_CARS.values():
        result[BRANCH_ID_TO_CITYNAME.get(car_branch)] += number_of_cars
    print(result)