Problem mit Dictionaries

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
yannik0802
User
Beiträge: 5
Registriert: Freitag 23. Dezember 2016, 13:46

Guten Abend zusammen,

ich versuche aktuell ein kleines Programm zu schreiben, das mir CSV Daten aus einer Datei ausliest und diese für weitere Rechenoperationen verfügbar macht.

Ich bin relativ unerfahren in der Programmierung mit Python, daher komme ich aktuell leider nicht weiter.

Im Folgenden mein Code:

Code: Alles auswählen


import csv

class Data:
    
    def __init__(self, datei, trenner):
        self.datei = datei
        self.trenner = trenner
       
        self.data = {}
        self.sortedDict = {}

    def readData(self):
        with open(self.datei) as csvfile:
            readCSV = csv.reader(csvfile, delimiter=self.trenner)
            for row in readCSV:
                self.data.update({ row[0] : float(row[4])})


    def sortByKey(self):
        self.sortedDict = sorted(self.data.items(), key = lambda t:t[0])

    def printSortedDict(self):
        for row in self.sortedDict:
            print(row)

    def printSortedRow(self, datep):
        test = self.sortedDict[datep]
        print(test)
Mit der Funktion readData() lese ich 7 Werte (im OHLC-Format) aus der Datei aus und selektiere die benötigten Positionen, in meinem nur zwei davon (Time + Close)

Mit diesen beiden Werten möchte ich nun weiter arbeiten und möglichst irgendwann mit den Close-Werten rechnen. Daher speichere ich die Time-Variable als String zusammen mit der Close-Variable als float in einem Dictionary und sortiere dieses nach der String-Variable.

Wenn ich die Funktion printSortedDict() aufrufe, werden mir nun alle Werte in sortierter Reihenfolge ausgegeben, ungefähr so:

"2015-01-01", 10045,2525
"2015-01-02". 10065,2352
...

Soweit so gut. Mein Problem ist nun Folgendes: Ich wäre gerne in der Lage einzelne Reihen aus dem sortedDict über die string-variable, also das Datum, aufzurufen.

Versucht habe ich das testweise über die Funktion printSortedRow(), ein Aufruf wäre dann wie folgt:

Code: Alles auswählen

data1 = Data('DAX1.txt', ',')
data1.readData()
data1.sortByKey()
data1.printSortedRow('2016-05-11')
Ich hatte gehofft, dass ich über data1.printSortedRow("2016-05-11") die entsprechende Reihe aufrufen kann, allerdings funktioniert das leider nicht. Ich habe mittlerweile tausend unterschiedliche Techniken probiert und komme hier leider nicht weiter.

Als Error erhalte ich immer: TypeError: list indices must be integers or slices, not str

Gibt es irgendeine Technik, über die ich mittels einer string-Variable eine zugehörige float-Variable ansteuern kann?

Ich freue mich über jegliche Anregung und bedanke mich schon mal herzlich im Vorraus. :)
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

`sorted` hat nicht das Ergebnis, was du denkst - `sorted` liefert eine Liste zurück, keine Dict. Deshalb kannst du darauf auf "nur" mit einem Index zugreifen, nicht mit Schlüsseln.

Wenn deine Eingabedatei die Werte bereits sortiert enthält, dann kannst du als Datentypen ein OrderedDict aus dem Collections-Modul nehmen. Dann wird die Reihenfolge der Schlüssel beibehalten.

Abgesehen davon: um auf den Wert eines Schlüssels zuzugreifen ist das Sortieren überflüssig. Das geht auch so.

Das `update` ist beim Einlesen auch überflüssig - du kannst neue Schlüssel-Werte-Paare einfach über `data['schlüssel'] = Wert` hinzufügen.

Funktionsnamen schreibt man in der Regel klein_mit_unterstrich, nicht CamelCase.

Übrigens: anstatt so was selber zu implementieren, könntest du auch mal auf http://pandas.pydata.org/. Das ist für das Rechnen mit so Daten gemacht.

Gruß, noisefloor
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@yannik0802: Dein Problem ist, dass sortedDict kein Wörterbuch ist, sondern eine Liste. Daran erkennt man, dass man am besten den Datentyp nicht in den Namen schreibt, weil der ist unter Umständen falsch. Wenn Du auf Werte per Zeit zugeifen willst, dann nimm doch data.

Übrigens ist die Klasse ziemlich sinnfrei, weil man nur eine Liste/Wörterbuch damit speichert, was man auch direkt könnte. `dict.update` mit einem gerade erzeugten Wörterbuch mit nur einem Eintrag aufzurufen ist umständlich, dazu gibt es die eckigen Klammern. Die Variablennamen halten sich nicht an die Konvention.

Das könnte auch so aussehen:

Code: Alles auswählen

import csv
 
def read_data(datei, trenner):
    with open(datei) as csvfile:
        data = csv.reader(csvfile, delimiter=trenner)
        return {row[0]: float(row[4]) for row in data}

def print_sorted(data):
    for time, value in sorted(data.items()):
        print(time, value)


def main():
    data = read_data("balba.csv", ";")
    print_sorted(data)
    print(data["2015-01-01"])
yannik0802
User
Beiträge: 5
Registriert: Freitag 23. Dezember 2016, 13:46

Danke für Eure schnellen Antworten,

dass mir sorted eine Liste zurückgibt wusste ich nicht. Ich werde gleich mal versuchen die Elemente direkt über data aufzurufen.

@Sirius3: Eine Klasse habe ich einfach mal so erstellt, das Programm (und auch die Klasse) sind ja noch lange nicht fertig.

Falls weitere Probleme auftreten, melde ich mich nochmal. :)

Edit: Der Aufruf über data hat funktioniert, vielen Dank. :)
Antworten