dictionary während iteration ändern, woruaf achten?

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
Scholastik
User
Beiträge: 53
Registriert: Freitag 7. Juli 2017, 12:35

Hallo :)

ich wusste leider nicht wie ich die Frage bei google sinnvoll formulieren kann um Lösungen zu finden, deswegen mach ichs lieber hier:

Wann ist es möglich/sinnvoll in einem dictionary einträge während des iterierens zu ändern und wann nicht?

Code: Alles auswählen

data = {"a":5}
for key, value in data.items():
    if value==5:
        data[key]= 10
print(data)

data = {"a":5}
for key, value in data.items():
    if value==5:
        value= 10 # wirkungslos
print(data)
Die Änderung von value hat keinen Einfluss auf data.

Code: Alles auswählen

data = {"Hase":{"Preis":0,"Menge":1},"Hund":{"Preis":0,"Menge":0}}
for k,entry in data.items():
    if entry["Menge"]==1:
        entry["Preis"] = 5
print(data)
Doch hier hat die Änderung von entry Einfluss auf data.

Kann man also vereinfacht sagen, wenn der zu verändernde Wert ein dictionary oder eine Liste ist, dann gehts und sonst nicht?

Oder sollte man, um auf Nummer sicher zu gehen, lieber immer alles voll ausschreiben, also im letzten Beispiel auch sicherheitshalber lieber:
data[k]["Preis"] = 5
schreiben? Sich also eine Vorgehensweise angewöhnen, die immer richtig ist, als es ausversehen falsch zu machen?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Scholastik: das hat nichts mit Schleifen zu tun. Du kannst die entscheidenden Zeilen isoliert betrachten:

Code: Alles auswählen

data[key]= 10
value= 10
entry["Preis"] = 5
Und da sollte klar werden, warum der zweite Fall nichts bewirkt, denn es wird nur ein Wert an eine Variable zugewiesen, während es in den anderen Fällen Indexzuweisungen sind.
Scholastik
User
Beiträge: 53
Registriert: Freitag 7. Juli 2017, 12:35

Sirius3 hat geschrieben:@Scholastik: das hat nichts mit Schleifen zu tun. Du kannst die entscheidenden Zeilen isoliert betrachten:

Code: Alles auswählen

data[key]= 10
value= 10
entry["Preis"] = 5
Und da sollte klar werden, warum der zweite Fall nichts bewirkt, denn es wird nur ein Wert an eine Variable zugewiesen, während es in den anderen Fällen Indexzuweisungen sind.
ja genau.
Doch ich dachte value und entry wären beides nur "zusammenhanglose" Variablen. Also wenn value nichts bringt, dachte ich dass entry auch nichts bringt.
Im Fall von value verändere ich eine neue Variable und im Fall von entry verändere ich ein neues dictionary.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Scholastik hat geschrieben:Im Fall von value verändere ich eine neue Variable und im Fall von entry verändere ich ein neues dictionary.
Wie kommst du auf "neues" Dictionary? Du verwendest doch in der Schleife das bestehende Dictionary.
Scholastik
User
Beiträge: 53
Registriert: Freitag 7. Juli 2017, 12:35

ok, also fassen wir zusammen:

Es hat nichts prinzipiell mit der schleife zu tun, sondern vereinfacht könnte man auch sagen:

Code: Alles auswählen

value = data[key] # eine zahl
value = 10 # ändert data nicht

entry = data[k] # ein dictionary
entry["Preis"] = 5 # verändert data
und dies wiederum kommt durch das allgemeine verhalten von dictionaries zustande, dass ein "=" nur ein Zeiger ist und keine neues objekt erzeugt.

Das mit den Zeigern ist immernoch ziemlich schwer zu merken für mich. Ich muss jedesmal scharf nachdenken, ob ein Zeiger reicht, oder ich eine flache/tiefe Kopie machen muss (wobei Zeiger und flache Kopie glaub ich dasselbe ist?!)
Gibt es da vllt eine Eselsbrücke wie man sich das leicht merken kann?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Scholastik: es gibt in Python keine Zeiger, also ist das Bild das Du hast, falsch. Es gibt nur Objekte und Namen, mit denen man auf diese Objekte zugreifen kann.

`value` verwiest mal an auf das eine Objekt, mal auf ein anderes Objekt. Woher das Objekt kam, ist egal:

Code: Alles auswählen

value = data[key] # eine zahl
value = 10 # eine andere Zahl
Dass die eine Zahl aus einem Wörterbuch kommt und die andere direkt angegben ist, ist egal.

Eine Indexzuweisung wird zwar auch mit `=` geschrieben, ist aber etwas ganz anderes.

Code: Alles auswählen

entry = data[k] # ein dictionary
entry["Preis"] = 5 # verändert entry, aber nicht data. 
`data` wird durch die Indexzuweisung an `entry` nicht gändert. Es wird nur der Inhalt des Wörterbuchs, auf den im Moment `entry` verweist, und das auch über `data[k]` erreichbar ist, geändert.
Antworten