Datensaetze aus ner Datenbank sinnvoll abbilden

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
shakebox
User
Beiträge: 175
Registriert: Montag 31. März 2008, 17:01

Servus, ich mal wieder!

Ich rufe aus einem Pythonscript mittles eines Fremdmoduls Datensaetze einer Filemakerdatenbank ab und bekomme ne Liste mit je einem Dictionary pro Datensatz zurueck. Drei Werte aus jedem Datensatz sind fuer mich relevant: Projektname, Shotname, Versionsnummer, wobei die Datensaetze auch genau nach diesen 3 Feldern sortiert sind. Inhaltlich koennte das dann so etwa aussehen:

Code: Alles auswählen

projektA    001_010    00
projektA    001_010    05
projektA    001_010    07
projektA    002_010    00
projektA    002_010    11
projektA    002_010    11b
projektA    003_010    04
projektB    101_010    00
projektB    101_010    01
projektB    101_010a   00
projektB    101_010a   05
usw.
Nun wuerde ich in Python gern unterschiedliche Sachen mit diesen Daten machen, z.B. fuer jeden Shot von jedem Projekt die hoechste Versionsnummer rausfinden oder die niedrigste oder so.

Nun fehlt mir aber voellig der Plan, wie man das jetzt am besten in Python abbildet, um da gut ranzukommen. Nutzt man da verschachtelte Dictionaries? Also z.B. ein Dictionary, wo jedes Projekt einen Key ergibt, der dann wieder ein Dictionary enthaelt mit jedem Shot als Key? Und dann die Versionen als Listen-Value davon? So dass ich so z.B. dann auf die hoechste Version eines Shots zugreifen koennte:

Code: Alles auswählen

p['projektA']['001_010'][-1]
Wenn ja, wie legt man denn sowas an aus der vorhandenen Datensatzliste? Ein einzelnes Dictionary nacheinander mit Key/Value-Paaren zu fuellen kann ich. Leeres Dict anlegen und dann Schrittweise fuellen, klar.

Aber so ne verschachtelte Struktur, da beisst es fuer mich aus vom Koennen her. Denn um etwas zu nem Dict bzw. ner Liste hinzufuegen zu koennen, muss ich ja jeweils vorher ne leere Version davon anlegen. Wenn es den Key aber schon gibt, darf ich natuerlich nicht nochmal das leere Objekt anlegen, sondern muss es ergaenzen.

Gibt es dafuer irgendwelche sinnvollen Konzepte, oder ist das einfach ne Verschachtelung von If-Abfragen nach dem Motto: Projekt schon vorhanden? Wenn nein: leg neuen Projekt-Key an mit leerem Dict-Value. Wenn ja: Shotname schon vorhanden? Wenn ja, Liste schon vorhanden? Ja, dann ergaenze neue Version, wenn nein, lege Liste an, etc., etc., etc.

Oder bin ich mit diesen verschachtelten Dicts/Listen total auf dem Holzweg und es gibt in Python viel sinnvollere Methoden, sowas abzubilden?

Danke fuer jeglichen Input und lieben Gruss,
Shakebox
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Sinnvoll wäre die Daten gar nicht abzubilden. Schieb sie einfach in eine sqlite Datenbank und nutze Queries um deine Abfragen zu machen.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@shakebox: wenn die von Dir beschriebene Zugriffsart die einzige ist, dann sind verschachtelte Wörterbücher das richtige. Deine Fragen sollte collections.defaultdict beantworten.
BlackJack

@shakebox: Dich könnte `collections.defaultdict` interessieren. Solche verschachtelten Datenstrukturen können auch unübersichtlich werden. Je nach dem was man mit den Daten machen möchte, kann es sich irgendwann auch lohnen das in eigene Datentypen zu kapseln.
shakebox
User
Beiträge: 175
Registriert: Montag 31. März 2008, 17:01

Danke Euch schonmal, 'defaultdict' kannte ich tatsaechlich noch nicht. Das sieht schonmal sehr hilfreich aus. Hilft mir aber erstmal "nur" fuer die zweite Ebene, sprich das Shotnamen-Dict mit der jeweiligen Liste drin, richtig? Das Projekt-Dict "drumrum" muesste ich dann schon selbst noch drumrumbauen, denn ich kann ja nicht was schreiben wie "defaultdict(defaultdict(list))", richtig?

Dass das ab ner bestimmten Komplexitaet dann unuebersichtlich wird ist mir klar. Fuer das was ich als "Auswertungsfunktionen" in dem Fall brauche reicht mir aber vermutlich die automatische "Intelligenz" von Listen, deshalb war die Idee das so anzugehen. Eigene Datentypen anzulegen ueberfordert mich vermutlich leider wieder schnell :(

@DasIch: von SQL hab ich leider so gar keine Ahnung, deshalb waere das glaub ne Hausnummer zu hoch fuer mich, auch wenn es vermutlich die sauberste Loesung waere.

Danke allerseits, dass wieder was gelernt habe. Sowas wie die 'collections' findet man halt nicht so leicht, wenn man nicht schon weiss dass es sie gibt ;-)
BlackJack

@shakebox: ``defaultdict(lambda: defaultdict(list))`` kann man aber schreiben.
shakebox
User
Beiträge: 175
Registriert: Montag 31. März 2008, 17:01

Ui, ich bin verbluefft und begeistert, danke vielmals.

Leider hab ich auch den "lambda" noch ueberhaupt nicht verstanden, der ist noch ein ziemliches Mysterium fuer mich. Aber mit jeder Anwendung davon komm ich dem Geheimnis hoffentlich ein wenig naeher. Klappt auf jeden Fall wunderbar, so sieht das schon fast elegant aus :wink:
BlackJack

@shakebox: ``lambda`` erzeugt eine Funktion die keinen Namen hat. Gäbe es das nicht, müsste man vorher eine Funktion mit einem Namen definieren und dann diese Funktion übergeben:

Code: Alles auswählen

def create_default():
    return defaultdict(list)

data = defaultdict(create_default)
Alternativ ginge noch die `partial()`-Funktion:

Code: Alles auswählen

from functools import partial

data = defaultdict(partial(defaultdict, list))
Antworten