Seite 1 von 1

Bei dynmaisch erzeugtem Dictionary wird ein Wert überall eingefügt

Verfasst: Dienstag 30. Mai 2023, 14:13
von nieselfriem
Hallo zusammen,

ich habe ein Dictionary in folgender Ausprägung.

Code: Alles auswählen

version_infos_actuator_dict = {
    'env1': {'aachen': {'aachen_actuator_infos': '', 'infos2': {}}, 'berlin': {'aachen_actuator_infos': '', 'infos2': {}}},
    'env2': {'dortmund': {'aachen_actuator_infos': '', 'infos2': {}}, 'stuttgart': {'aachen_actuator_infos': '', 'infos2': {}}}
}
dieses soll dann gefüllt werden mit infos aus

Code: Alles auswählen

vers_info = {"env1" : {'aachen': {"build": "aachen_actuator_infos"}}}
mit folgender schleife

Code: Alles auswählen

    for env, city in vers_info.items():
        for city_name, city_data in vers_info.items():
            version_infos_actuator_dict[env][city_name]['actuator_infos'] = city_data
Das funktioniert soweit richtig, wenn ich version_infos_actuator_dict fest im Code definiert habe

Sobald ich aber version_infos_actuator_dict mit der unten stehende Funktion init_version_infos_actuator_dict erzeugen lasse. Werden die Daten city_data in alle Subdictionaries actuator_infos eingefügt.


Statt

Code: Alles auswählen

version_infos_actuator_dict = {
    'env1': {'aachen': {'actuator_infos': 'aachen_actuator_infos', 'infos2': {}}, 'berlin': {'actuator_infos': '', 'infos2': {}}},
    'env2': {'dortmund': {'actuator_infos': '', 'infos2': {}}, 'stuttgart': {'actuator_infos': '', 'infos2': {}}}
}
passiert das

Code: Alles auswählen

version_infos_actuator_dict = {
    'env1': {'aachen': {'actuator_infos': 'aachen_actuator_infos', 'infos2': {}}, 'berlin': {'actuator_infos': 'aachen_actuator_infos', 'infos2': {}}},
    'env2': {'dortmund': {'actuator_infos': 'aachen_actuator_infos', 'infos2': {}}, 'stuttgart': {'actuator_infos': 'aachen_actuator_infos', 'infos2': {}}}
}

Code: Alles auswählen

def init_version_infos_actuator_dict(all_cities, all_envs):
    #all_cities = {'aachen': 'ahc', 'berin': 'ber', 'dortmund': 'dor', 'Stuttgard', 'stut'}
    #all_envs ['env1', 'env2'] 
    infos_dict = {}
    # init_infos = json.dumps({'actuator_infos': "", 'helm_infos': {}})
    init_infos = {'actuator_infos': "", 'helm_infos': {}}
    for env in all_envs:
        for city in all_cities:
            if not infos_dict.get(env):
                infos_dict[env] = {city: init_infos}
            else:
                infos_dict[env].update({city: init_infos})
    #print(infos_dict)
    return infos_dict
Woran liegt das, dass ich so komische Effekte habe, wenn ich das Dictionary dynamisch erzeugen lasse?

Re: Bei dynmaisch erzeugtem Dictionary wird ein Wert überall eingefügt

Verfasst: Dienstag 30. Mai 2023, 14:36
von __blackjack__
@nieselfriem: Es wird nicht in alle subdictionaries eingefügt sondern in das *eine* Wörterbuch das Du da mehrfach einfügst. Das Wörterbuch das an `init_infos` gebunden wird, gibt es genau *einmal*, halt an verschiedenen Stellen in `infos_dict`.

`update()` ist die falsche Methode wenn man genau *ein* Schlüssel/Wert-Paar eintragen will. Dafür muss man nicht ein Wörterbuch der Länge 1 erstellen was danach auch gleich wieder verworfen wird. Wenn `infos_dict` ein `collections.defaultdict` wäre, könnte man das auch einfacher ausdrücken.

Ungetestet:

Code: Alles auswählen

def init_version_infos_actuator_dict(city_name_to_abbreviation, envs):
    result = defaultdict(dict)
    for env in envs:
        for city_name in city_name_to_abbreviation.keys():
            result[env][city_name] = {"actuator_infos": "", "helm_infos": {}}
    # print(result)
    return result

Re: Bei dynmaisch erzeugtem Dictionary wird ein Wert überall eingefügt

Verfasst: Dienstag 30. Mai 2023, 14:59
von __blackjack__
Wobei ich mich gerade Frage was das überhaupt soll, denn das es ein `env` im Ergebnis schon gibt, kann ja nur vorkommen wenn Werte in `envs` mehrfach vorkommen, aber selbst dann würde ja alles was beim vorherigen mal dort eingetragen wurde komplett überschrieben. Also ist das eigentlich das hier:

Code: Alles auswählen

def init_version_infos_actuator_dict(city_name_to_abbreviation, envs):
    return {
        env: {
            city_name: {"actuator_infos": "", "helm_infos": {}}
            for city_name in city_name_to_abbreviation.keys()
        }
        for env in envs
    }

Re: Bei dynmaisch erzeugtem Dictionary wird ein Wert überall eingefügt

Verfasst: Dienstag 30. Mai 2023, 15:30
von nieselfriem
Es funktioniert. Aber ich verstehe es noch nicht ;)

Ich werde mich aber mal damit beschäftigen. Danke

Re: Bei dynmaisch erzeugtem Dictionary wird ein Wert überall eingefügt

Verfasst: Dienstag 30. Mai 2023, 15:41
von __blackjack__
Eine Zuweisung von einer Datenstruktur speichert *diese* Datenstruktur, und keine Kopie davon. Du hast halt *ein* Wörterbuch, das über verschiedene Wege erreichbar, aber halt immer das selbe Objekt ist.

Code: Alles auswählen

In [2]: a = {}

In [3]: b = {"Berlin": a, "Hamburg": a}

In [4]: b
Out[4]: {'Berlin': {}, 'Hamburg': {}}

In [5]: a is b["Berlin"]
Out[5]: True

In [6]: a is b["Hamburg"]
Out[6]: True

In [7]: b["Berlin"] is b["Hamburg"]
Out[7]: True

In [8]: a["answer"] = 42

In [9]: a
Out[9]: {'answer': 42}

In [10]: b
Out[10]: {'Berlin': {'answer': 42}, 'Hamburg': {'answer': 42}}

In [11]: b["Berlin"]["active"] = True

In [12]: a
Out[12]: {'answer': 42, 'active': True}

In [13]: b
Out[13]: 
{'Berlin': {'answer': 42, 'active': True},
 'Hamburg': {'answer': 42, 'active': True}}