Inhalt von Listen in Dict oder Dict in Dict etc.

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
sandra84
User
Beiträge: 17
Registriert: Mittwoch 9. Juni 2010, 06:34

Hallöle,

ich hätte mal ne Frage und zwar habe ich folgendes kleine Beispiel

Code: Alles auswählen

dDict1 = {}
dDict2 = {}
lList = []

lList.append ("Test1")

dDict1 = {1: "Test0", "bla":lList}
dDict2 = {1: dDict1}
print dDict2

lList.append ("Test2")
print dDict2

del lList[0:len(lList)]

print "nach löschen"
print dDict2

Raus kommt dann

Code: Alles auswählen

{1: {1: 'Test0', 'bla': ['Test1']}}
{1: {1: 'Test0', 'bla': ['Test1', 'Test2']}}
nach löschen
{1: {1: 'Test0', 'bla': []}}
Warum das so ist kann ich mir erklären. Aber wie kann ich es umgehen, dass wenn ich eine Liste in ein Dict kippe, die Änderungen an der Liste nicht gleich mit reinkommen? Jmd ne idee?

Für das einfache Beispiel wüsste ich wie ich es umgehen kann, aber ich parse gerade unmengen an Daten aus verschiedenen Datenquellen und such eine Möglichkeit alles im Speicher zu ordnen etc. um es dann irgendwohin zu schreiben. Dafür muss ich aber mit bestimmten Ständen der Liste arbeiten während der Verarbeitung.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Code: Alles auswählen

dDict1 = {1: "Test0", "bla":lList}
zu

Code: Alles auswählen

dDict1 = {1: "Test0", "bla":lList[:]}
oder

Code: Alles auswählen

dDict1 = {1: "Test0", "bla":copy.deepcopy(lList)}
Je nachdem, ob `lList` verschachtelt ist, wenn nicht reicht das erste.

Die Namen sind btw denkbar schlecht, auch wenn es nur ein Beispiel ist.
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

Hi,

mit

Code: Alles auswählen

dDict1 = {1: "Test0", "bla":lList}
packst du ja nicht die Liste an sich in das Dict, sondern nur einen "Namen" bzw. Zeiger auf die Liste. Wenn du die Liste änderst, macht das dem zeiger recht wenig.

Willst du einen Stand "speichern", musst die die Liste mit dem gewünscht Stand kopieren
sandra84
User
Beiträge: 17
Registriert: Mittwoch 9. Juni 2010, 06:34

Ahjo und wie mach ich das dann mit Dict in dict?
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Builtin-Typen kann man meist einfach mit dem Konstruktor kopieren. Also list(aList), dict(aDict).
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Dics haben eine copy-Methode; deepcopy geht genauso.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Deepcopy ist aber in 99% der Fälle nicht das, was man benutzten möchte aber es gibt ja auch die allgemeine copy.copy-Funktion.

Warum dicts eine copy-Methode haben und Listen nicht ist mir allerdings schleierhaft, weswegen ich es gar nicht erst erwähnt habe.
Zuletzt geändert von Darii am Donnerstag 24. Juni 2010, 12:56, insgesamt 2-mal geändert.
sandra84
User
Beiträge: 17
Registriert: Mittwoch 9. Juni 2010, 06:34

ja aber copy ist ja tatsächlich nicht das was ich brauche. wenn ichs richtig gelesen hab
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Das musst du selbst wissen. Wir wissen ja schließlich nicht, was du von dem Dict im Dict erwartest.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Darii hat geschrieben:arum dict-Methoden eine copy-Methode haben und Listen nicht ist mir allerdings schleierhaft
Mir auch. :roll:
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

Darii hat geschrieben:Deepcopy ist aber in 99% der Fälle nicht das, was man benutzten möchte
Warum?
Hier z.B. würde es ja passen, oder nicht?

Code: Alles auswählen

In [1]: a = ["a"]

In [2]: b = {1:a}

In [3]: b
Out[3]: {1: ['a']}

In [4]: a.append("b")

In [5]: b
Out[5]: {1: ['a', 'b']}

In [6]: import copy

In [7]: c = copy.deepcopy(b)

In [8]: c
Out[8]: {1: ['a', 'b']}

In [9]: a.append("c")

In [10]: c
Out[10]: {1: ['a', 'b']}

In [11]: b
Out[11]: {1: ['a', 'b', 'c']}

In [12]: a
Out[12]: ['a', 'b', 'c']
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

@.robert: Da list(lList), lList[:], copy.copy(lList) und copy.deepcopy(lList) in diesem Fall alle genau das gleiche machen, ist es relativ egal, was man nimmt. (Nebenbei: copy.deepcopy ist sicherlich die langsamste Variante.)

Einen Unterschied macht es vor allem dann, wenn die Liste selbst wieder mutable Objekte enthält, z.B.

Code: Alles auswählen

import copy
 
a = [[2, 3, 5], range(1000000)]
b = a[:]
c = copy.deepcopy(a)
a[1][3] = "Hallo"
 
print b[1][:5]
print c[1][:5]

Code: Alles auswählen

[0, 1, 2, 'Hallo', 4]
[0, 1, 2, 3, 4]
Und die Erfahrung zeigt, dass man fast nie deepcopy will. (Wenn man es doch braucht, weiß man das meist schon beim Schreiben.)

Edit: Sorry, ging ein bisschen an deinem Post vorbei. In dem kopierst du aber den container - darum will die OP aber gar nicht.
Die vorgeschlagene Lösung war, die Liste beim Einfügen zu kopieren, und darauf beziehen sich meine Anmerkungen - deshalb passts nicht so zu deinem Beitrag.
Zuletzt geändert von bords0 am Donnerstag 24. Juni 2010, 13:28, insgesamt 1-mal geändert.
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

Aber genau hier geht ja ja nicht um "copy.copy(List)" sondern um copy.copy(Dict-mit-dict-mit-list), und da ist copy und deepcopy eben was anderes und afaik deepcopy genau das was man braucht. Eben weil das dict ja mutable Objecte enthält.
Antworten