Textdatei spaltenweise auslesen und schreiben

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
bartmouse
User
Beiträge: 3
Registriert: Mittwoch 18. Januar 2017, 11:31

Hallo,

ich versuche aus einer Datei die 1,2 und 4 Spalte auszulesen und als 1,2,3 Spalte in eine
andere Datei zu speichern. Aber irgend etwas mache ich falsch, bekomme ständig eine Fehlermeldung.
Kann mir jemand sagen was ich falsch mache?
Vielen Dank!

So sieht zB eine Datei aus, welche ich auslesen möchte:

Code: Alles auswählen

 1050.000  -590.000  -178.834                 .00000  
 1050.000  -580.000  -178.834                 .00000 
 1050.000  -570.000  -178.834                 .00000 
 1050.000  -560.000  -178.834                 .00000 
 1050.000  -550.000  -178.834                 .00000 
 1050.000  -540.000  -178.834                 .00000 
 1050.000  -530.000  -178.834                 .00000 
 1050.000  -520.000  -178.834                 .00000 
 1050.000  -510.000  -178.834                 .00000 
 1050.000  -500.000  -178.834                 .00000 
Das ist das Pythonscript, welches ich geschrieben habe. Hiermit versuche ich die ersten zwei Spaltenwerte
zu lesen und zu schreiben. Aber das klappt schon nicht...

Code: Alles auswählen

fileaus=open('fileaus.txt','w')
inpreseat=open('endpres_C.val','r')
for line in inpreseat:
	line = inpreseat.readline()
	pair=line.split("  ")
	x=str(pair[0])
	y=str(pair[1])
	fileaus.write('%s,%s\n' %(x,y))
inpreseat.close
fileaus.close
Viele Grüße!
Zuletzt geändert von Anonymous am Mittwoch 18. Januar 2017, 12:24, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@bartmouse: Was heisst „klappt nicht“ und welche Fehlermeldungen genau?

Ein Fehler hier ist, dass Du nur jede zweite Zeile verarbeitest, weil Du sowohl mit Schleife über die Zeilen gehst, als auch in der Schleife noch mal Zeilen aus der Datei liest über die Du iterierst. Wobei da eventuell sogar noch Verwirrenderes passieren kann, nämlich wenn der Zeileniterator mehr als eine Zeile in einen internen Pufferspeicher liest und `readline()` davon nichts weiss und direkt auf der Datei operiert, ohne zusätzlichen Puffer.

Die Dateien werden nicht wieder geschlossen. Dazu müsste man die `close()`-Methode auch *aufrufen*. Noch besser wäre es aber die Dateien zusammen mit der ``with``-Anweisung zu verwenden um das Schliessen am Ende zu garantieren.

`pair` ist als Name falsch, denn so wie die Daten aussehen führt der `split()`-Aufruf zu mehr als einem Paar, also mehr als zwei Elementen im Ergebnis.

`str()` mit Zeichenketten als Argumenten aufzurufen macht keinen Sinn. Was soll das bewirken?

Ich würde `split()` ohne Argument benutzen. Und zum Schreiben der Daten das `csv`-Modul.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

bartmouse hat geschrieben:ich versuche aus einer Datei die 1,2 und 4 Spalte auszulesen und als 1,2,3 Spalte in eine
andere Datei zu speichern.
Warum benennst du das Ergebnis im Code dann "pair"? split() liefert dir eine variable Zahl an Teilstücken, die durch das "Zerhacken" mit dem angegebenen Trenner entstehen. Unter "pair" würde ich genau 2 Stück verstehen, was aber wie gesagt nicht unbedingt zutreffen muss (bei deinen Beispielzeilen trifft es garantiert nicht zu). Ohne Argumente verwendet split() Whitespace, was oft flexibler ist als die Angabe eines Leerzeichens. Wenn man die Spalten anders angeordnet haben möchte, dann ist itemgetter() recht hilfreich:

Code: Alles auswählen

from operator import itemgetter

TEST_TEXT = """\
1050.000  -590.000  -178.834                 .00000  
1050.000  -580.000  -178.834                 .00000
1050.000  -570.000  -178.834                 .00000
1050.000  -560.000  -178.834                 .00000
1050.000  -550.000  -178.834                 .00000
1050.000  -540.000  -178.834                 .00000
1050.000  -530.000  -178.834                 .00000
1050.000  -520.000  -178.834                 .00000
1050.000  -510.000  -178.834                 .00000
1050.000  -500.000  -178.834                 .00000"""


def main():
    get_items = itemgetter(0, 1, 3)
    for line in TEST_TEXT.splitlines():
        items = get_items(line.split())
        print('  '.join(items))


if __name__ == '__main__':
    main()
Zu beachten ist natürlich, dass der Index in Python bei 0 beginnt. Daher ist 0, 1, 3 die Übersetzung von 1, 2, 4.

Falls man itemgetter weglassen möchte, dann wäre es:

Code: Alles auswählen

parts = line.split()
items = parts[0], parts[1], parts[3]
bartmouse
User
Beiträge: 3
Registriert: Mittwoch 18. Januar 2017, 11:31

Hallo,

danke für die Antworten. Habe meinen Code nun vereinfacht um zunächst die 0. und 1. Spalte auszulesen und zu schreiben:

Code: Alles auswählen

fileaus=open('fileaus.txt','w')
inpreseat=open('endpres_C.val','r')
for line in inpreseat:
	parts=line.split()
	x=parts[0]
	y=parts[1]
	fileaus.write('%s,%s\n' %(x,y))
inpreseat.close
fileaus.close
Sollte doch funktionieren, bekomme aber die Fehlermeldung ´'indexError: list index out of range'

Was mache ich falsch?
Zuletzt geändert von Anonymous am Freitag 20. Januar 2017, 12:27, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@bartmouse: In welcher Zeile tritt die Ausnahme auf? Dann weisst Du ja welcher Index nicht stimmt. Dann gib doch vor dem Zugriff mal `parts` aus und schau woran das liegen könnte.

Edit: Du schliesst die Dateien immer noch nicht.
bartmouse
User
Beiträge: 3
Registriert: Mittwoch 18. Januar 2017, 11:31

Hallo,

habe rausgefunden das der Fehler durch eine Leerzeile in der auszulesenden Datei entsteht. Wie ich das abfange muss
ich noch rausfinden.

Versuche aus zwei Dateien zu lesen und in eine Datei zu schreiben:

Code: Alles auswählen

fileaus=open('fileaus.txt','w')
inpreseat=open('endpres_C.val','r')
ininputC=open('input_C.val','r')
for line in inpreseat:
	xyparts=inpreseat.line.split()
	zparts=ininputC.line.split()
	x=xyparts[0]
	y=xyparts[1]
	z=zparts[4]
	fileaus.write('%s,%s,%s\n' %(x,y,z))
inpreseat.close
fileaus.close
ininputC.close
Bekomme jedoch einen Fehler das wohl die Schachtelung inpreseat.line.split() so nicht richtig ist. Kann ich hier nicht zeimal in verschiedenen Dateien splitten?

Ich dachte mit zB fileaus.close schließe ich die Datei. Ist das nicht so?

EDIT: Achje, die Klammern ()
Zuletzt geändert von Anonymous am Freitag 20. Januar 2017, 16:53, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@bartmouse: Das ist kein Problem der ”Schachtelung” sondern Du wirst die Meldung bekommen das Dateiobjekte kein `line`-Attribut haben. Objekte haben im allgemeinen nicht Attribute die man gerne hätte, sondern nur welche die implementiert und dokumentiert sind.

Dateiobjekte sind iterierbar, (sogar Iteratoren) und zwar liefern sie wenn man über sie iteriert (beziehungsweise die Elemente heraus holt) die Zeilen der Datei. Wenn Du über die Zeilen der beiden Dateien ”parallel” iterieren möchtest, dann schau Dir mal die `zip()`-Funktion (in Python 3) beziehungsweise `itertools.izip()` (in Python 2) an.
Antworten