Seite 1 von 1

Datenstruktur eines dict() importieren

Verfasst: Mittwoch 25. Mai 2011, 21:32
von mrshoul
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

Re: Datenstruktur eines dict() importieren

Verfasst: Mittwoch 25. Mai 2011, 21:40
von ms4py
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.

Re: Datenstruktur eines dict() importieren

Verfasst: Donnerstag 26. Mai 2011, 09:20
von mutetella
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

Re: Datenstruktur eines dict() importieren

Verfasst: Donnerstag 26. Mai 2011, 09:33
von mutetella
Oder suchst Du etwas wie eine dictionary-Vorlage?
Dann würde ich aus 'struktur' eine Klasse 'Artikel()' machen.

Was genau hast Du denn vor?

Re: Datenstruktur eines dict() importieren

Verfasst: Donnerstag 26. Mai 2011, 11:44
von mrshoul
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'}]

Re: Datenstruktur eines dict() importieren

Verfasst: Donnerstag 26. Mai 2011, 12:03
von mutetella
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

Re: Datenstruktur eines dict() importieren

Verfasst: Donnerstag 26. Mai 2011, 21:15
von mrshoul
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

Re: Datenstruktur eines dict() importieren

Verfasst: Donnerstag 26. Mai 2011, 23:30
von 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.

Re: Datenstruktur eines dict() importieren

Verfasst: Freitag 27. Mai 2011, 07:59
von mutetella
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

Re: Datenstruktur eines dict() importieren

Verfasst: Freitag 27. Mai 2011, 17:18
von mrshoul
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

Re: Datenstruktur eines dict() importieren

Verfasst: Freitag 27. Mai 2011, 17:44
von 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.

Re: Datenstruktur eines dict() importieren

Verfasst: Freitag 27. Mai 2011, 18:13
von mrshoul
Vielen Dank,
das ist ausgezeichnet erklärt.