Liste in Dictionary: selber Speicherbereich ?

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
WalterT
User
Beiträge: 31
Registriert: Dienstag 5. Dezember 2017, 16:00

Hallo,

ich hänge bei einem Problem, das ich nicht verstehe und wo ich nichts finde im Netz (wsl suche ich falsch)

Code: Alles auswählen

# eine Liste
itemlist = [0, 0, 0, 0, 0]
# ein Dictionary
dicty = {'Key': ''}
# Dictionary verändern
dicty['Key'] = itemlist
# Liste verändern
itemlist[0] = 1

# Dictionary ist auch verändert !!
print(dicty['Key'])
Warum ändert sich der Inhalt meines Dictionarys, wenn ich nur die Liste ändere?

Danke fürs Mitdenken und lg
Walter
Benutzeravatar
sparrow
User
Beiträge: 4536
Registriert: Freitag 17. April 2009, 10:28

Weil es die selbe Liste ist, die unterschiedlich referenziert wird.

Wenn bei deinem "Auto" die Batterie leer ist springt deine "Karre" nicht an. Egal wie du es nennst, es ist das selbe Objekt.
WalterT
User
Beiträge: 31
Registriert: Dienstag 5. Dezember 2017, 16:00

hm... bei einfachen Variablen ist das ja nicht so:

Code: Alles auswählen

value1 = 0
value2 = 2
value2 = value1
value1 = 1

print(value2)
# Ergebnis: 0, wie erwartet
# --------------------------------------------------


value1 = [0, 0, 0]
value2 = [1, 1, 1]
value2 = value1
value1[0] = 1

print(value2)
# Ergebnis [1, 0, 0]
Es hat irgendwas mit dem Typ "list" zu tun, ich komme aber nicht drauf, wie ich das behandeln soll...
Benutzeravatar
sparrow
User
Beiträge: 4536
Registriert: Freitag 17. April 2009, 10:28

Die Dokumentation erklärt das ganz gut. Wenn Objete unveränderbar sind, dann werden sie jedes mal neu erstellt, wenn sie an einen Namen gebunden werden. a = b = 1 bedeutet also, dass a und be den gleichen Wert haben, nicht jedoch das selbe Objekt referenzieren. Integer sind unveränderlich (immutable). a = b = [1, 2, 3] bedeutet, dass eine neue Liste erstellt, wird und diese Liste sowohl an den Namen a und b gebunden wird. Egal unter welchen Namen sie angesprochen wird, es ist immer die selbe Liste.
Das macht ja auch Sinn. Stell dir mal vor, man hat eine riesige Liste und steckt die in eine andere Liste oder in ein dict - und der Rechner hisst die weiße Fahne, weil im Speicher riesige Datenmengen kopier werden.

Wenn du die Kopie einer Liste haben möchtest, dann macht man eine Kopie.

Vielleicht solltest du dein grundlegendes Problem beschreiben, dass du versuchst mit dem Einfügen des der Liste in das dict zu lösen.
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Wenn dich das Verhalten interessiert kannst du hier auch mehr darüber lesen.
WalterT
User
Beiträge: 31
Registriert: Dienstag 5. Dezember 2017, 16:00

Danke für die Erklärung, hab es kapiert.

so gehts:

Code: Alles auswählen

value1 = [0, 0, 0]
value2 = [1, 1, 1]
value2 = list(value1) # <<<<<<<<
value1[0] = 1

print(value2)
# Ergebnis [0, 0, 0]
warum mach ich das? Eigentlich aus Faulheit und weil es mir effizient erscheint für meine Anwendung. Ich hab ein Dictionary mit u.a. einem Key, dessen Value eine Liste mit 25 floats ist. Darin speichere ich jede Stunde (0 bis 24) und eine Tagessumme (25) mit Leistungswerten aus meiner PV-Anlage.

Aus Bequemlichkeit speichere ich das gesamte Dictionary "as is" als Textdatei immer wieder ab. Ein Flask liest diese Textdatei und gibt sie mir 1:1 als json für das javascript im Layout.

Jetzt lese ich die Dokumentationen, die ihr erwähnt habt....

Besten Dank und lg
Walter
Benutzeravatar
__blackjack__
User
Beiträge: 14032
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@WalterT: Da ist jetzt soweit ich das sehe keine Erklärung warum Du das machst. Warum muss da eine Liste kopiert werden?

In *einer* Liste Werte speichern bei denen *ein* Wert etwas anderes bedeutet als die anderen ist auch keine gute Idee. Zumal sich die Tagessumme aus den anderen Werten doch berechnen lässt.

Dictionary ”as is” als Textdatei speichern meint hoffentlich als JSON mit dem `json`-Modul und nicht einfach `str()`.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
WalterT
User
Beiträge: 31
Registriert: Dienstag 5. Dezember 2017, 16:00

`str()` funktioniert ohnehin so einfach nicht, da ich meine Daten ja wieder lese und da kann ich kein str() brauchen. Natürlich verwende ich das json-Modul, so kann ich meine Daten lesen und schreiben und im javascript des Frontend (HTML und js) brauche ich auch nichts mehr zu machen, als zu lesen.

Die Tagessumme könnte natürlich auch die Summe aller Stundenwerte sein, aber es ist im Ablauf einfacher, neben den Stunden 00:00 bis 23:00 auch einen Wert 24:00 in der Liste zu führen und zu bedienen, da brauche ich nicht immer zu iterieren...

lg
Walter
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

sparrow hat geschrieben: Mittwoch 10. Februar 2021, 15:18 Die Dokumentation erklärt das ganz gut. Wenn Objete unveränderbar sind, dann werden sie jedes mal neu erstellt, wenn sie an einen Namen gebunden werden. a = b = 1 bedeutet also, dass a und be den gleichen Wert haben, nicht jedoch das selbe Objekt referenzieren.
Das stimmt aber nicht wirklich. Ein a = b = dein_objekt bindet immer das selbe Objekt sowohl an a als auch an b. Das ist nicht mal etwas CPython-spezifisches, sondern vom Sprachdesign so vorgesehen. Es lässt sich auch leicht ausprobieren:

Code: Alles auswählen

>>> a = b = 1
>>> a is b
True
>>> a = b = 10000
>>> a is b
True
Womöglich verwechselt du das mit

Code: Alles auswählen

a = 10000
b = 10000
print(a is b)
# -> False
Antworten