Seite 1 von 1
Alternative zu copy.deepcopy
Verfasst: Mittwoch 27. November 2013, 19:07
von Nobuddy
Hallo zusammen,
im Moment arbeite ich ausschließlich mit Dictionaryś, die Daten dazu werden aus csv-Dateien verwendet.
Insgesamt sind es 40 Dictionarys mit einem Gesamtvolumen von ca. 50 MB.
Ich stelle mal in sehr vereinfachter Form dar, wie ich es mir vorgestellt habe.
Code: Alles auswählen
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import copy
filename = {0 : 'file1', 1 : 'file2', 2 : 'file3'}
a = {0 : {0 : 'abc', 1 : 'hier etwas', 2 : 'was anderes'},
1 : {0 : '000', 1 : 'hier 111', 2 : 'was 222'},
2 : {0 : 'iii', 1 : 'ooo etwas',2 : 'ddd anderes'},
}
c = copy.copy(a)
# c = copy.deepcopy(a)
name1 = a.get(0)
name2 = a.get(1)
name3 = a.get(2)
dictname = {0 : name1, 1 : name2, 2 : name3}
name1.update({0 : {0 : 'hui', 1 : 'hier etwas', 2 : 'was anderes'}})
[a.update({i : dictname[i]}) for i in dictname]
for i in filename:
if a.get(i) != c.get(i):
print('Daten wurden verändert!')
print(a)
print(c)
Das Problem ist, daß mit copy.copy(data) nach einer Änderung in a auch c von der Änderung betroffen ist.
Bei copy.deepcopy(data) ist das nich der Fall, allerdings dauert der Kopiervorgang ein 10-faches von copy.copy(data).
Nun würde ich gerne wissen, welche brauchbare Alternative es dazu gibt?
Grüße Nobuddy
Re: Alternative zu copy.deepcopy
Verfasst: Mittwoch 27. November 2013, 19:29
von BlackJack
@Nobuddy: Eine „lies meine Gedanken und kopiere nur was ich möchte”-Funktion gibt's nicht.
Du könntest andere Datenstrukturen nehmen, zum Beispiel persistente Abbildungen die man nicht verändern kann, sondern wo jede Operation eine Kopie liefert, die aber so implementiert sind, dass das sowohl vom Speicher als auch von der Laufzeit effizienter ist als ein `deepcopy()` von einem `dict`. Das Modul `burrahobbit` bietet so etwas zum Beispiel.
Re: Alternative zu copy.deepcopy
Verfasst: Mittwoch 27. November 2013, 19:42
von Nobuddy
BlackJack hat geschrieben:@Nobuddy: Eine „lies meine Gedanken und kopiere nur was ich möchte”-Funktion gibt's nicht.
So eine Funktion, habe ich auch nicht gesucht.
BlackJack hat geschrieben:Du könntest andere Datenstrukturen nehmen, zum Beispiel persistente Abbildungen die man nicht verändern kann, sondern wo jede Operation eine Kopie liefert, die aber so implementiert sind, dass das sowohl vom Speicher als auch von der Laufzeit effizienter ist als ein `deepcopy()` von einem `dict`. Das Modul `burrahobbit` bietet so etwas zum Beispiel.
Habe mal etwas gegoogelt, allzuviel ist darüber nicht zu lesen, obwohl das Wenige sich gut anhört.
Mein Englisch ist leider sehr bescheiden, ich weiß nicht ob Du Dich noch erinnerst ....
Gibt es da irgendwie ein einfaches und verständliches Beispiel, über diese Anwendung?
Re: Alternative zu copy.deepcopy
Verfasst: Mittwoch 27. November 2013, 19:55
von BlackJack
Die Dokumentation ist hier:
http://segfaulthunter.github.io/burraho ... index.html
Da ist auch ein Beispiel drin und die Methoden aufgelistet die es gibt. Viel komplizierter wird es nicht.
Re: Alternative zu copy.deepcopy
Verfasst: Mittwoch 27. November 2013, 19:59
von Nobuddy
Danke, werde mir die Doku anschauen.
Grüße Nobuddy
Re: Alternative zu copy.deepcopy
Verfasst: Freitag 29. November 2013, 15:57
von Nobuddy
Die Doku ist schon sehr interessant, jedoch brauche ich da mehr Zeit zum umsetzen, welche mir momentan fehlt.
Für eine kurzfristige Lösung, bräuchte ich nochmals Euren Input.
Gibt es bei Directoryś eine Möglichkeit, den Zustand vor und nach Änderung festzustellen?
Z.B. Hashwert, Zeitstempel ... oder?
Grüße Nobuddy
Re: Alternative zu copy.deepcopy
Verfasst: Freitag 29. November 2013, 18:45
von BlackJack
@Nobuddy: Man könnte eine Kopie (mit `copy.deepcopy()`) erstellen und die danach rekursiv vergleichen um heraus zu finden was sich geändert hat. *Ob* sich etwas geändert hat, sollte man mit ``==`` feststellen können. Was auch rekursiv alles durchgeht.
Einen Hash-Wert kann man so direkt nicht berechnen:
Code: Alles auswählen
In [43]: hash({'answer': 42})
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/bj/<ipython-input-43-d7c7a91b87df> in <module>()
----> 1 hash({'answer': 42})
TypeError: unhashable type: 'dict'
Re: Alternative zu copy.deepcopy
Verfasst: Samstag 30. November 2013, 09:48
von Nobuddy
@BlackJack: Die Alternative mit copy.deepcopy() war mir klar, welche ich aber aus Gründen der Performance, nicht benutzen möchte.
Die Fehlermeldung, beim ermitteln des Hashwertes, habe ich auch feststellen müssen.
Die Vorteile von Dictionaryś zu Listen, sind ganz klar.
Einziger Wermutstropfen ist, daß eine Differenz nicht mehr so leicht und schnell zu ermitteln ist.
Einzige Alternative, was ich momentan sehe, ist alle Dictionaryś wieder in die Dateien abzuspeichern .... bis ich das mit burrahobbit’s umsetzen kann.
Egal, ob Daten verändert wurden oder nicht.
Re: Alternative zu copy.deepcopy
Verfasst: Samstag 30. November 2013, 11:45
von Sirius3
@Nobuddy: Daten speichern, verändern und dann noch tief verschachtelte Bäume miteinander vergleichen? was für ein Problem möchtest Du eigentlich mit Deinen Dictionaryś lösen?
Re: Alternative zu copy.deepcopy
Verfasst: Samstag 30. November 2013, 12:12
von Nobuddy
@Sirius3: Ich verwende 1 Haut-Directonary, in dem viele (ca. 50) Directorys enthalten sind.
Diese Haut-Directonary wird von einem externen Modul erstellt und an das Arbeits-Modul übergeben.
Diese angesprochenen Unter-Directonarys können je nach Bedarf von Änderungen betroffen sein.
Letztendlich übergebe ich das Haut-Directonary wieder an das externe Modul zum Speichern der Daten zurück.
Da evtl. z.B. 5 von den 50 Unter-Directonarys geändert wurden, müßten nur 5 Dateien aktualisiert werden, wenn eine einfache und schnelle Differenzierung zu geändert und nicht geändert möglich wäre.
Alternativ, wie schon angesprochen, aktualisiere ich alle 50 Dateien, ob geändert oder nicht geändert.
Re: Alternative zu copy.deepcopy
Verfasst: Samstag 30. November 2013, 12:36
von snafu
Das heißt, dich interessieren die Änderungen eigentlich nur auf Dateisystemebene? In dem Fall könntest du dir nämlich einfach die Änderungszeiten der Dateien anschauen. In Fällen, wo diese anders als beim letzten Durchsehen waren (in aller Regel: aktueller), würdest du dir den Inhalt ansehen, ob er sich tatsächlich geändert hat. Oder bin ich da komplett auf dem falschen Dampfer und du meinst etwas anderes?
Re: Alternative zu copy.deepcopy
Verfasst: Samstag 30. November 2013, 14:06
von Nobuddy
Hallo snafu,
klar die Änderungszeiten, kann ich in den Dateien anschauen, das ist nicht das Problem.
Directoryś werden aus Dateien erstellt, in denen dann Änderungen entstehen können.
Hier sollten nur die Dateien aktualisiert werden, bei denen das Directory geändert wurde.
Was jetzt sehr umständlich wäre, wenn ich jetzt das Directory in eine Liste umwandle, die betreffende Datei als Liste lade, um zu ermitteln ob es eine Differenz gibt.
Welche Möglichkeiten habe ich bei Directoryś, Differenzen zu ermitteln, ohne mit copy.deepcopy() hantieren zu müssen?
Re: Alternative zu copy.deepcopy
Verfasst: Samstag 30. November 2013, 14:16
von BlackJack
@Nobuddy: Ganz allgemein kann man das nur wenn man vorher eine Kopie erzeugt und hinterher schaut ob sich etwas geändert hat.
Man könnte natürlich auch ein „flag” pro Wörterbuch welches zu einer Datei gehört speichern und das immer dann setzen wenn man in dem Wörterbuch etwas ändert.
Die Wörterbücher in Listen umwandeln und mit den tatsächlichen Dateiinhalten zu vergleichen ist mehr Aufwand als die Daten einfach alle zu speichern, unabhängig davon ob sich etwas geändert hat oder nicht.
Re: Alternative zu copy.deepcopy
Verfasst: Samstag 30. November 2013, 14:46
von Nobuddy
BlackJack hat geschrieben:Die Wörterbücher in Listen umwandeln und mit den tatsächlichen Dateiinhalten zu vergleichen ist mehr Aufwand als die Daten einfach alle zu speichern, unabhängig davon ob sich etwas geändert hat oder nicht.
Ja, das ist momentan außer 'burrahobbit’s', die beste und einfachste Möglichkeit.
