Letzte Zeile eines CSV auslesen

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
Korea-2003
User
Beiträge: 25
Registriert: Mittwoch 23. April 2008, 13:47

Hallo,

ich habe folgendes Problem.
Ich lade mir ein CSV File in mein Python Programm.
Nun will ich die letzte beschriebene Zeile dieses CSV Files ausgegeben bekommen bzw. löschen, da dort immer nur die Anzahl aller Einträge steht.
Mein bisheriger Code:

Code: Alles auswählen

...
primeFile = 'Prime.csv'
separator = ";"

priF = file(primeFile, 'r')

content1 = priF.readlines()[2:]
...
Wie lautet der Befehl dafür? Habe schon überall gesucht, aber noch keine wirkliche Lösung gefunden.

MfG :)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Das letzte Item bekommst du mit ``[-1]``, aber ich habe das gefühl, dass du dir erst mal das Modul ``csv`` ansehen solltest.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
chrisxx8
User
Beiträge: 27
Registriert: Mittwoch 4. Mai 2016, 15:16

Hey,
ich schreibe einfach mal hier weiter anstatt nen neuen Thread aufzumachen.
Und zwar möchte ich immer die letzte Zeile einer csv Datei lesen, und wenn diese Zeile = xyz ist möchte ich diese Zeile löschen.
Jemand nen kleines beispiel für mich? das mit der ``[-1]`` verstehe ich nicht ganz..

Alternativ wäre es auch gut wenn ich immer die vorletzte Zeile nur erweitern würde. Wichtig ist halt das am Anfang und am Ende meiner Datei immer das gleiche steht, und in der Mitte meine Werte eingefügt werden.
Danke
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@chrisxx8: Text-Dateien zu ändern ist immer mit sehr großen Aufwand verbunden, und lohnt sich eigentlich nur, wenn man wirklich viele Daten in einer Datei hat, obwohl es dann sowieso ratsam wäre, ein anderes Dateiformat zu wählen. Die einfache Lösung ist also, eine neue Datei anzulegen, bei der die letzte Zeile nach Deinen Wünschen geändert geschrieben wird.
chrisxx8
User
Beiträge: 27
Registriert: Mittwoch 4. Mai 2016, 15:16

@Sirius3
Du meinst quasi ich lese oder öffne meine vorhandene Datei, schreibe nur die letzte Zeile und speicher sie unter einen anderen Namen ab?
Wenn ja hast du einen kleinen beispiel Code für mich? Habe mir schon die Doku angeschaut des CSV Modules doch leider ist mein Englisch nicht so gut :?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Du musst keinen anderen Namen verwenden. Das Problem ist dass du bei Textdateien eigentlich nur die ganze Datei neuschreiben oder etwas anhängen kannst. Den Inhalt irgendwie zu verändern ist nicht wirklich möglich und Zeilen löschen ist grundsätzlich keine Option. Dementsprechend liest du den Inhalt aus, löscht ggfs. die letzte Zeile und schreibst dann den veränderten Inhalt in die Datei.
Benutzeravatar
snafu
User
Beiträge: 6736
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wenn der Speicherverbrauch kein Problem ist, dann kann man die Zeilen einfach komplett einlesen:

Code: Alles auswählen

with open(dateiname) as infile:
    lines = infile.readlines()
    lines.pop()  # Entfernt letzte Zeile
with open(dateiname, 'w') as outfile:
    outfile.writelines(lines)
Andernfalls den Weg über eine `for`-Schleife gehen.
chrisxx8
User
Beiträge: 27
Registriert: Mittwoch 4. Mai 2016, 15:16

@snafu
bekomme die Fehlermeldung 'file' object has no attribute 'writeline' Ich denke so wie du den code geschrieben hast ist es noch nicht ganz fertig?
Irgend wo muss ja jetzt meine Zeile rein die immer als letztes stehen soll?
Dateiname ist der Komplette pfard mit Dateiname ?
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@chrisxx8
Die Methode heißt auch nicht `writeline` sondern `writelines`…
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
snafu
User
Beiträge: 6736
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

chrisxx8 hat geschrieben:@snafu
bekomme die Fehlermeldung 'file' object has no attribute 'writeline' Ich denke so wie du den code geschrieben hast ist es noch nicht ganz fertig?
Irgend wo muss ja jetzt meine Zeile rein die immer als letztes stehen soll?
Dateiname ist der Komplette pfard mit Dateiname ?
1. Es heißt `writelines()` (mit "s" am Ende).

2. Wenn eine veränderte Zeile mit rein soll, dann nutze

Code: Alles auswählen

lines[-1] = "dein text\n"
. Das "-1" steht für die letzte Zeile. "-2" würde für die vorletzte Zeile stehen, usw. Das "\n" ist wichtig, weil damit eine neue Zeile begonnen wird (\n = newline).

3. Es ist entweder eine relative oder eine absolute Pfadangabe möglich. Hauptsache die Datei wird gefunden.
Benutzeravatar
snafu
User
Beiträge: 6736
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Man könnte ja auch einfach mal einen Nachmittag lang ein Python-Tutorial durcharbeiten. Dann würde sich vieles von selbst erklären. Aber das ist wahrscheinlich zuviel verlangt...
chrisxx8
User
Beiträge: 27
Registriert: Mittwoch 4. Mai 2016, 15:16

Erst mal ein Dankeschoen fuer die Hilfe hier.
Es funktioniert leider noch nicht, die letzte Zeile wird nicht geschrieben.
Hier meine aktuelle Funktion:

Code: Alles auswählen

def WirteKML(GPSValues_,PathKML, sendenKML):

        csvFile = open(PathKML, "a")
        writer = csv.writer(csvFile, delimiter=',', lineterminator='\n', quoting=csv.QUOTE_NONE, quotechar='', escapechar=' ')
        if os.path.getsize(PathKML) == 0:
            row = []
            row.append('<?xml version="1.0" encoding="UTF-8"?>\n<kml xmlns="http://www.opengis.net/kml/2.2">\n<Document>')
            writer.writerow(row)
        row = []
        row.append("<Placemark><name>%s" % GPSValues_[0])
        row.append("</name><description>Hier koennten Analogwerte stehen</description><Point><coordinates>%s" % GPSValues_[2])
        row.append("%s</coordinates></Point></Placemark>\n" % GPSValues_[1])
        writer.writerow(row)
        csvFile.close()

        with open(PathKML) as infile:
            lines = infile.readlines()
            #lines.pop()
        with open(PathKML, 'w') as outfile:
            outfile.writelines(lines)
            lines[-1] = "</Document></kml>\n"

        if (sendenKML.AOK_Lesen() == 1):
            filename = os.environ['HOME'] + "/GPSDaten.kml"
            os.remove(filename)
            print
            print "KML Datei geloescht"
            print
            sendenKML.AOK_Setzen(0)
Zum Thema Turtorial habe ich mir schon einiges auf youtube angeschaut und bin auch weiter gekommen, nur finde ich nicht immer genau das was ich Suche..
BlackJack

@chrisxx8: Okay, wir sind hier im völlig falschen Thema! Das ist ja gar kein CSV sondern XML und das sollte man mit einer entsprechenden XML-Bibliothek verarbeiten und ganz sicher nicht mit dem `csv`-Modul. XML sollte man auch nicht als Textdatei behandeln, also weder irgendwie zeilenweise verarbeiten, noch mit normalen Zeichenkettenoperationen auf dem Inhalt operieren. XML ist kompliziert und zerbrechlich, sowie da auch nur eine Kleinigkeit nicht stimmt, ist es kein XML mehr und Programme die XML erwarten weigern sich dann komplett irgendetwas mit so einer Datei anzufangen.

In der Standardbibliothek gibt es die ElementTree-API und mit `lxml` ein externes Package das auch diese API bietet, aber auch ein bisschen mehr Funktionalität.

Was Tutorials angeht: Lesen und durcharbeiten ist da wohl besser als irgendwelche Videos von Youtube. Du kannst geschriebenes in dem Tempo durcharbeiten das Dir liegt und nicht mit dem Tempo das vom Video vorgegeben wird. Und *durcharbeiten* ist ernst gemeint: Weder von Videos noch vom geschriebenem sollte man sich einfach so berieseln lassen und hoffen das irgend etwas hängen bleibt, sondern aktiv selber Wissen erarbeiten in dem man mindestens den Stoff praktisch nachvollzieht, aber auch selber überlegt was bei Veränderungen passiert, dann etwas verändert, und falls das nicht den Erwartungen entspricht, herausfindet *warum nicht*. Auch kann man in Videos schlecht gezielt zu einer Stelle springen, während man Texte leicht durchsuchen kann.

Die gezeigte Funktion macht den Eindruck als hättest Du überhaupt nicht verstanden was das Problem ist und den Code von snafu da einfach mitten rein kopiert, in der Hoffnung, dass das auf magische Weise irgendwie das Problem löst. So funktioniert Programmieren nicht.
chrisxx8
User
Beiträge: 27
Registriert: Mittwoch 4. Mai 2016, 15:16

@BlackJack
Also meine Funktion funktioniert eig ganz gut, ich würde gerne auch weiter mit dem csv-modul arbeiten. Ich speicher die Datei einfach als .kml ab.
Ich meine es funktioniert ja so, die .kml Datei wird sauber von dem nachfolgenden Programm verarbeitet, wieso soll ich das dann ändern?
Das einzige Problem ist nun das am Ende immer `</Document></kml>` stehen muss.

Kann ich die Datei 1 nicht unter einen anderen Namen abspeichern (Datei2)
->dann Datei2 öffnen
->und dann `</Document></kml>` ans Ende hängen

Somit wäre Datei1 immer ohne `</Document></kml>` und Datei2 immer mit `</Document></kml>`
BlackJack

@chrisxx8: Deine Funktion funktioniert nicht ganz gut, zum einen weil Du dann die Frage hier nicht geschrieben hättest, zum anderen weil das total kaputt ist was Du da machst. Wie gesagt ist es falsch XML-Dateien als normale Textdateien mit Zeilen und Zeichenkettenoperationen zu behandeln und das dann auch noch mit dem `csv`-Modul zu machen ist extrem daneben. Das Dir das bis jetzt noch nicht um die Ohren geflogen ist, heisst nicht das die Funktion grundsätzlich funktioniert. Man kann Sicherungen auch einfach durch einen Draht ersetzen. Das funktioniert. Solange bis einem das Haus deswegen abfackelt. Du solltest das ändern weil es schlicht falsch ist. Die Struktur von XML-Dateien sind keine Textzeilen sondern die Struktur wird durch die Tags vorgegeben. Und diese lassen sich wiederum nicht so einfach mit Zeichenkettenoperationen zerlegen, da braucht man einen XML-Parser für. Umgekehrt kann man auch nicht einfach so Text irgendwo in eine Zeichenkettendarstellung des Dokuments einfügen und davon ausgehen dass das danach immer noch gültiges XML ist.
chrisxx8
User
Beiträge: 27
Registriert: Mittwoch 4. Mai 2016, 15:16

So habe die Kiste jetzt an laufen gebracht, habe mittels shutil die Datei unter nem anderen Namen dupliziert und dann mein `</Document></kml>` angehängt.
@BlackJack
cool das du dich hier so reinhängst, kann das schon nachvollziehen das der Code totale Grütze ist, aber momentan habe ich keine andere Wahl als es so hinzubiegen, mir fehlen einfach umfangreiche Kenntise im Python. Im S7 Bereich würdest du mich nicht so Basteln sehen^^ da ist alles Solid. Vielleicht mache ich mach nen Python Einsteiger Kurs, fände ich sehr interresant.
Benutzeravatar
snafu
User
Beiträge: 6736
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Dir fehlen nicht nur Python-Kenntnisse, dir fehlen auch Kenntnisse von diversen wichtigen Datenformaten. Da ist so einiges dabei, was jeder ernstzunehmende Programmierer zumindest in seinen Grundzügen verstehen sollte. Falls es dein Ziel ist, einigermaßen sinnvoll zu programmieren, dann hast du noch einiges nachzuholen. Im Moment ißt du dein Schnitzel im übertragenen Sinne mit dem Löffel, weil es ja so gut funktioniert und man damit prima schneiden kann...
BlackJack

@chrisxx8: Wenn Du Programmieren im Allgemeinen und Python im Besonderen überhaupt gar nicht verstehen möchtest, warum stellst Du dann hier Fragen? Zu zeigst schlechten und falschen Code, weisst selbst das das schlechter Code ist, ignorierst vorsätzlich Antworten, warum dann also überhaupt fragen? Das macht keinen Sinn. :K
Antworten