Alternative zu copy.deepcopy

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
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

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
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.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

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. :wink:
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?
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.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

Danke, werde mir die Doku anschauen.

Grüße Nobuddy
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

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. :wink:

Gibt es bei Directoryś eine Möglichkeit, den Zustand vor und nach Änderung festzustellen?
Z.B. Hashwert, Zeitstempel ... oder?

Grüße Nobuddy
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'
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

@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.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@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?
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

@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.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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?
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

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?
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.
Nobuddy
User
Beiträge: 994
Registriert: Montag 30. Januar 2012, 16:38

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. :wink:
Antworten