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

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
Benutzeravatar
nieselfriem
User
Beiträge: 135
Registriert: Sonntag 13. Januar 2013, 16:00

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?
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

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
    }
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
nieselfriem
User
Beiträge: 135
Registriert: Sonntag 13. Januar 2013, 16:00

Es funktioniert. Aber ich verstehe es noch nicht ;)

Ich werde mich aber mal damit beschäftigen. Danke
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

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}}
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten