Seite 1 von 1

Liste in Dictionary: selber Speicherbereich ?

Verfasst: Mittwoch 10. Februar 2021, 13:04
von WalterT
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

Re: Liste in Dictionary: selber Speicherbereich ?

Verfasst: Mittwoch 10. Februar 2021, 13:08
von sparrow
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.

Re: Liste in Dictionary: selber Speicherbereich ?

Verfasst: Mittwoch 10. Februar 2021, 13:32
von WalterT
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...

Re: Liste in Dictionary: selber Speicherbereich ?

Verfasst: Mittwoch 10. Februar 2021, 15:18
von sparrow
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.

Re: Liste in Dictionary: selber Speicherbereich ?

Verfasst: Mittwoch 10. Februar 2021, 15:32
von Jankie
Wenn dich das Verhalten interessiert kannst du hier auch mehr darüber lesen.

Re: Liste in Dictionary: selber Speicherbereich ?

Verfasst: Mittwoch 10. Februar 2021, 18:19
von WalterT
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

Re: Liste in Dictionary: selber Speicherbereich ?

Verfasst: Mittwoch 10. Februar 2021, 22:38
von __blackjack__
@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()`.

Re: Liste in Dictionary: selber Speicherbereich ?

Verfasst: Mittwoch 17. Februar 2021, 16:08
von WalterT
`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

Re: Liste in Dictionary: selber Speicherbereich ?

Verfasst: Mittwoch 17. Februar 2021, 18:00
von snafu
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