Datenstruktur eines dict() importieren

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
mrshoul
User
Beiträge: 10
Registriert: Sonntag 22. November 2009, 10:10

Hallo Python-Spezialisten,
habe eine Anfängerfrage bei der ich im Forum nicht fündig geworden bin.

Ich möchte die Struktur eines "dict()" mit import importieren. Geht das nur wenn ich in der externen Datei eine Funktion definiere?

Folgendermassen soll das nach meiner Vorstellung aussehen. Externe Datei "daten_struktur.py":

Code: Alles auswählen

struktur = {'Bezeichnung':'',
            'Preis':0,
            'Anzahl':0}
Hauptprogramm:

Code: Alles auswählen

import daten_struktur
Kann ich auf diese Weise die Struktur importieren? Und wenn, wie greife ich darauf zu?

Grüße,

mrshoul
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Ja, das funktioniert prinzipiell so. Mit `daten_struktur.struktur` kannst du darauf zugreifen.

Als Format zum Serialisieren würde ich aber eher JSON, YAML oder Pickle empfehlen.
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Schau' Dir mal das hier an. Damit kannst Du ein dictionary erstellen und abspeichern.
Die Datei, die Du dadurch erhältst, schaut dann in etwa so aus, wie Du das mit 'daten_struktur.py' versuchst. Abhängig davon, welches Format (csv, json oder pickle) Du angibst.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Oder suchst Du etwas wie eine dictionary-Vorlage?
Dann würde ich aus 'struktur' eine Klasse 'Artikel()' machen.

Was genau hast Du denn vor?
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
mrshoul
User
Beiträge: 10
Registriert: Sonntag 22. November 2009, 10:10

Moin, und danke für Eure Antworten
mutetella hat geschrieben:Oder suchst Du etwas wie eine dictionary-Vorlage?
Dann würde ich aus 'struktur' eine Klasse 'Artikel()' machen.

Was genau hast Du denn vor?
Ja, es soll eine Vorlage werden. Ich möchte eine Liste erstellen die für jeden Listenpunkt die gleiche Dict-Vorlage benuttzt, die aber jeweils eigene Werte haben.

Ungefär so (und natürlich erweiterbar):

Code: Alles auswählen

a_list = [{'Bezeichnung':'Milch','Preis':0.9,'Einheit':'1 l','Anzahl':2,'Ort':'viv'},
          {'Bezeichnung':'Salami','Preis':.99,'Einheit':'100 g','Anzahl':1,'Ort':'Mezger'}]
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Wie schon gesagt, ich würde in diesem Fall statt dictionaries eher Klassenexemplare verwenden:

Code: Alles auswählen

class Ware(object):
    def __init__(self, bezeichnung, preis, gebinde, anzahl, lagerort):
        self.bezeichnung = bezeichnung
        self.preis = preis
        self.gebinde = gebinde
        self.anzahl = anzahl
        self.lagerort = lagerort
Damit legst Du für jeden Artikel ein Exemplar der Klasse 'Ware()' an. 'Ware()' dient Dir somit quasi als Vorlage für einen Artikel.

Code: Alles auswählen

In [269]: artikel = [Ware(bezeichnung='Milch', preis=0.9, gebinde=1, anzahl=2, lagerort='viv'), Ware(bezeichnung='Salami', preis=0.99, gebinde=100, anzahl=1, lagerort='Metzger')]

In [270]: artikel[0].bezeichnung
Out[270]: 'Milch'

In [271]: artikel[1].bezeichnung
Out[271]: 'Salami'
Das ganze hat dann noch ungeahnte Möglichkeiten wenn es darum geht, Deine Waren zu verwalten... :wink:

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
mrshoul
User
Beiträge: 10
Registriert: Sonntag 22. November 2009, 10:10

Zuerst mal vielen Dank für Eure Hilfe. Die Anregungen sind wirklich spitze. In diesem Projekt wollte ich aber gern mit Ditionarys arbeiten und das ist mir letztlich auch folgendermaßen gelungen:

Externe Datei mit Namen "ware.py":

Code: Alles auswählen

struktur = {'Bezeichnung':'',
            'Preis':0,
            'Gebinde':'',
            'Anzahl':0,
            'Lagerort':''}
nach dem Import habe ich die Daten in einer "for" schleife in das dict eingelesen und nach jedem Durchlauf eine Kopie des Dictionarys in der einer Liste gespeichert.

Code: Alles auswählen

import ware

daten = list()      # hier sind bei mir die importierte Daten gespeichert
# importier, importier ...
orderListe = list() # Liste für die Ditionaries

for row in daten:
    ware.struktur['Bezeichnung']=row[0]
    ware.struktur['Preis']=float(row[1])
    ware.struktur['Gebinde']=row[2]
    ware.struktur['Anzahl']=int(row[3])
    ware.struktur['Lagerort']=row[4]
    orderListe.append(ware.struktur.copy())

Mir gefällts ganz gut so. Mich würde aber noch interessieren was der Vorteil von pickle und Konsorten in diesem Kontext ist.

Grüße,

mrshoul
BlackJack

@mrshoul: Wenn Du das mit kopieren löst, würde ich erst die Struktur kopieren und dann die Kopie erst befüllen. Es erscheint mir allerdings etwas sinnlos eine Vorlage zu haben, die letztendlich gar nicht gebraucht wird, weil *alles* darin überschrieben wird. Besser wäre es nicht zu kopieren sondern in `ware` die Informationen bereit zu stellen, die nötig sind um ein neues Dictionary aus einer `row` zu erstellen. Das wären die Schlüssel und eine Umwandlungsfunktion für die jeweiligen Elemente von `row`:

Code: Alles auswählen

STRUKTUR = [
    ('Bezeichnung', str),
    ('Preis', float),
    ('Gebinde', str),
    ('Anzahl', int),
    ('Lagerort', str),
]
Das erstellen der Bestellungsliste könnte dann so aussehen:

Code: Alles auswählen

import ware
from itertools import izip

orders = [
    dict((k, f(v)) for ((k, f), v) in izip(ware.STRUKTUR, row)) for row in daten
]
Der konkrete Datentyp sollte nicht in Namen auftauchen, denn das bekommt man Probleme wenn man den mal ändern möchte.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

mrshoul hat geschrieben:Mich würde aber noch interessieren was der Vorteil von pickle und Konsorten in diesem Kontext ist.
Du hast ja für Deine Daten eine Liste 'daten', die Du, man glaubt es kaum, von irgendwoher mit Daten füllst. Diese Liste voll mit Daten willst Du ja nach dem Programmende nicht verlieren.
Eine Liste, ein dictionary oder Klassen als Datenpool lassen sich aber nicht so ohne weiteres abspeichern. Du musst diese Objekte erst einmal "zerlegen" und kannst dann ihre Bestandteile in eine Form bringen, die sich speichern lässt.
'pickle' hat gegenüber anderen Möglichkeiten den Vorteil, dass es für Dich das Zerlegen, sprich das Serialisieren der Objekte übernimmt. Du kannst also fast jedes Pythonobjekt ganz einfach abspeichern. Und wenn Du es dann wieder lädst, steht es in gleicher Form wieder bereit.
Nachteil von Lösungen wie 'pickle' oder 'shelve' ist, dass Du immer den gesamten Datenbestand speichern und laden musst. Und dadurch, dass Du nicht nur die Werte Deiner Daten, sondern auch Informationen der Strukturen, in denen Deine Daten liegen speicherst, ist ein späteres Abändern dieser Strukturen nicht so einfach möglich.
Zudem ist es auch nicht so ohne weiteres möglich, gepickelte Daten außerhalb der Pythonanwendung, mit der diese Daten erstellt wurden, zu verwenden.
Und die Vorteile, die Datenbanksysteme mit sich bringen, hast Du mit 'pickle' auch nicht.

Das klingt jetzt eher nach mehr Nachteilen als Vorteile. Man muss halt abwägen, was einem wichtig ist. Wenn man die Möglichkeiten, die ein Datenbanksystem bietet, letztlich nicht wirklich braucht, dann sind 'pickle', 'shelve', 'json' etc. 'ne tolle Sache, da sie schnell und problemlos implementiert sind.

Ach ja: 'json', 'yaml', 'csv' ... haben den Vorteil, dass die Datei, die Du damit erhältst, in einem Format vorliegt, das Du mit jedem Texteditor betrachten und bearbeiten kannst und mit vertretbarem Aufwand auch in andere Anwendungen importieren kannst.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
mrshoul
User
Beiträge: 10
Registriert: Sonntag 22. November 2009, 10:10

Vielen Dank BlackJack und mutella,
BlackJack hat geschrieben:

Code: Alles auswählen

orders = [
    dict((k, f(v)) for ((k, f), v) in izip(ware.STRUKTUR, row)) for row in daten
]
BlackJack Könntest Du mir bitte den Bereich "(k, f(v)) for ((k, f), v)" erklären? Dass es ein Dictionary wird ist klar.
"k" = key nehme ich an, aber wofür stehen "f" und "v" ?

Vielen Dank,

mrshoul
Zuletzt geändert von mrshoul am Freitag 27. Mai 2011, 23:03, insgesamt 1-mal geändert.
BlackJack

@mrshoul: `f` für Funktion und `v` für ”value”. Der Bereich den Du da rausgenommen hast um ihn erklärt zu bekommen ist alleine kein gültiger Ausdruck, darum kann man nur den Ausschnitt schlecht erklären. Schau Dir einfach mal die Teilausdrücke von innen nach aussen an, was da jeweils passiert:

Code: Alles auswählen

In [23]: STRUKTUR
Out[23]: 
[('Bezeichnung', <type 'str'>),
 ('Preis', <type 'float'>),
 ('Gebinde', <type 'str'>),
 ('Anzahl', <type 'int'>),
 ('Lagerort', <type 'str'>)]

In [24]: row
Out[24]: ['Milch', '0.75', '100', '2', 'Keller']

In [25]: list(izip(STRUKTUR, row))
Out[25]: 
[(('Bezeichnung', <type 'str'>), 'Milch'),
 (('Preis', <type 'float'>), '0.75'),
 (('Gebinde', <type 'str'>), '100'),
 (('Anzahl', <type 'int'>), '2'),
 (('Lagerort', <type 'str'>), 'Keller')]

In [26]: [(k, f(v)) for ((k, f), v) in izip(STRUKTUR, row)]
Out[26]: 
[('Bezeichnung', 'Milch'),
 ('Preis', 0.75),
 ('Gebinde', '100'),
 ('Anzahl', 2),
 ('Lagerort', 'Keller')]

In [27]: dict((k, f(v)) for ((k, f), v) in izip(STRUKTUR, row))
Out[27]: 
{'Anzahl': 2,
 'Bezeichnung': 'Milch',
 'Gebinde': '100',
 'Lagerort': 'Keller',
 'Preis': 0.75}
23: Da haben wir die Struktur die alle nötigen Informationen enthält um von einem Datensatz als Liste von Zeichenketten zu einem Dictionary für diesen Datensatz zu kommen.

24: Ein Beispielhafter Datensatz.

25: Struktur und Datensatz verbunden.

26: Die Umwandlungsfunktion auf den jeweiligen Wert aus der Datenstruktur angewendet.

27: Aus den Tupeln ein Dictionary erstellt.
mrshoul
User
Beiträge: 10
Registriert: Sonntag 22. November 2009, 10:10

Vielen Dank,
das ist ausgezeichnet erklärt.
Antworten