Problem mit Listenindex

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
Zizibee
User
Beiträge: 166
Registriert: Donnerstag 12. April 2007, 08:36

Montag 9. Juli 2007, 11:29

Tach zusammen,

ich habe eine beliebige Anzahl Dateien mit Messpunkten, die ich vergleichen will. Die ersten drei Zeilen in den Dateien bilden jeweils den Header, der immer gleich ist. Die eigentlichen Messpunkte sind in zwei Spalten aufgeteilt. Links stehen die Punkte an denen gemessen wird (das sind in jeder Datei auch immer die selben Punkte) und rechts das Messergebnis. Das sieht dann so aus:

Code: Alles auswählen

# linear
# x = Volt
# gnuplot> load'nolog.plt'
0.0		-6.73568
0.0252525252525		1.053074
0.0505050505051		4.852033
0.0757575757576		-7.805659
0.10101010101		3.272062
...
Von allen Messergebnissen der Dateien soll der Mittelwert gebildet und alles zusammen in eine neue Datei geschrieben werden. Also der Mittelwert von Datei1Messwert1 und Datei2Messwert1 usw...
Dafür wollte ich die Werte in Listen schreiben, um sie bequem auszulesen und berechnen zu können. Allerdings bereiten mir die Indizes in Python noch ziemlich Probleme.
Beim einlesen der ersten Datei gibt es noch keine Probleme, aber bei der zweiten kommt immer:
Traceback (most recent call last):
File "kglaettung.py", line 25, in <module>
ergebnisse = [str (i.split()[1]) for i in werte]
IndexError: list index out of range
Mein Code sieht bisher so aus:

Code: Alles auswählen

# -*- coding: cp1252 -*-
import tkFileDialog

anzahl = int(raw_input("Wie viele Kurven sollen verglichen werden?: "))

gesErgebnisse = []

for a in range(anzahl):

	datei = open(tkFileDialog.askopenfilename())	#laden
	werte = []						# ertellen bzw zuücksetzen
	
	for line in datei:
			werte.append(line)

	if a == 0:							# erste Datei
		header = werte[:3]				# Kopfzeile auslesen
		del werte[:3]					# Kopfzeile löschen
		messwerte = [str (i.split()[0]) for i in werte]
		ergebnisse = [str (i.split()[1]) for i in werte]
	
	else:
		ergebnisse = []					# ergebnisse zurücksetzen
		del werte[:3]
		ergebnisse = [str (i.split()[1]) for i in werte]
		
	gesErgebnisse.append(ergebnisse)		# verschachtelte Liste erzeugen
	
	datei.close()
Sieht jemand meinen Fehler?
Danke schonmal!
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Montag 9. Juli 2007, 11:46

Hallo Zizibee.

Das bedeutet, dass beim splitten in der zweiten Datei bei einer (oder mehreren) der Zeilen nur eine list mit einem Wert(index [0]) zurück kommt.
Müsstest du dir nochmal überlegen und genau angucken ob das splitten in der Form die richtige Lösung ist.
Zizibee
User
Beiträge: 166
Registriert: Donnerstag 12. April 2007, 08:36

Montag 9. Juli 2007, 12:14

:shock: Tatsache, es lag an den Dateien und nicht am Programm!
Bei der zweiten Datei, die ich testweise erstellt habe, hatte ich durch das rüberkopieren zwei Leerzeilen am Ende anstatt eine, das war schon der ganze Fehler! :roll:

Die Dateien hab ich nur mal so erstellt, weil die anderen mindestens 100 Messpunkte haben und deshalb etwas unübersichtlich sind. Die richtigen Dateien wurden aber alle von einem anderen Pythonprogramm erstellt, so dass dort das Problem nicht mehr vorkommen dürfte.

Vielen Dank! :D
BlackJack

Montag 9. Juli 2007, 12:42

Das kann man ein wenig zusammenstreichen. Namen an eine leere Liste binden, nur im sie ein oder zwei Zeilen danach an eine andere Liste zu binden ist überflüssig.

Zum einlesen einer Datei in eine Liste mit Zeilen braucht man keine Schleife. Man kann entweder `list()` benutzen oder die `readlines()`-Methode. Und schliessen würde ich die Datei gleich nach dem einlesen.

Wenn man aus den beiden Zweigen der ``if a == 0``-Abfrage die Gemeinsamkeiten heraus zieht, braucht man nur noch den ``if``-Teil. Und der `str()`-Aufruf in den "list comprehensions" ist überflüssig.

Code: Alles auswählen

for a in range(anzahl): 

    datei = open(tkFileDialog.askopenfilename())    #laden 
    werte = list(datei)
    datei.close()

    if a == 0:                            # erste Datei 
        header = werte[:3]                # Kopfzeile auslesen 
        messwerte = [i.split()[0] for i in werte]
    
    del werte[:3]
    ergebnisse = [i.split()[1] for i in werte]
    
    gesErgebnisse.append(ergebnisse)        # verschachtelte Liste erzeugen
Zizibee
User
Beiträge: 166
Registriert: Donnerstag 12. April 2007, 08:36

Montag 9. Juli 2007, 13:03

Und ich dachte ich hätte es schon halbwegs kompackt hinbekommen :)

Ein Fehler hat deine Umstellung aber und zwar sind bei dir bei den Messwerten (Zeile 9) auch noch teile vom Header mit drin, die ich bei meinem Code vorher schon gelöscht habe. Ich fürchte daher kommt man wohl doch nicht um das else herum.

Aber es ist echt erstaunlich, wie viel überflüssigen Code ich da drin habe...
BlackJack

Montag 9. Juli 2007, 14:34

Ups. :oops: Aber man könnte im ``if``-Zweig über ``werte[3:]`` statt nur ``werte`` iterieren. Dann stimmts wieder.
Zizibee
User
Beiträge: 166
Registriert: Donnerstag 12. April 2007, 08:36

Montag 9. Juli 2007, 15:04

BlackJack hat geschrieben:Ups. :oops: Aber man könnte im ``if``-Zweig über ``werte[3:]`` statt nur ``werte`` iterieren. Dann stimmts wieder.
und wenn man das bei ergebnisse (Zeile 12) auch macht, fällt noch das "del wert[:3]" weg. Das wird ja immer kürzer :shock:

Da das Programm jetzt funktioniert schreib ich es mal komplett hin, vielleicht sieht ja jemand noch etwas was man kürzer schreiben kann. Wenn wir schon dabei sind ;)

Code: Alles auswählen

# -*- coding: cp1252 -*-
import tkFileDialog

anzahl = int(raw_input("Wie viele Kurven sollen verglichen werden?: "))
gesErgebnisse = []
neuWerte = []

for a in range(anzahl):
	datei = open(tkFileDialog.askopenfilename())    #laden
	werte = list(datei)
	datei.close()

	if a == 0:                            # erste Datei
		header = werte[:3]                # Kopfzeile auslesen
		messwerte = [i.split()[0] for i in werte[3:]]

	ergebnisse = [i.split()[1] for i in werte[3:]]

	gesErgebnisse.append(ergebnisse)        # verschachtelte Liste erzeugen

ausgabe = str(header[0]) + str(header[1]) + str(header[2])
	
for n in range(len(ergebnisse)):
	summe = 0
	for m in range(len(gesErgebnisse)):
		summe = summe + float(gesErgebnisse[m][n])
	ausgabe = ausgabe + str(messwerte[n]) + '\t\t' + str(summe/anzahl) + '\n'

file_ = tkFileDialog.asksaveasfilename(filetypes = [('Mittelwertkurve.gnu','.gnu')])
if file_:
	f = file(file_, 'w')
	f.write (ausgabe)
	f.close()
else:
	tkMessageBox.showerror('Error','Bitte einen Dateinamen eintragen!')
BlackJack

Montag 9. Juli 2007, 16:32

Wenn man sowas wie ``for i in range(len(obj)):`` schreibt, benutzt man in 99% der Fälle einen unnötigen Index. Man kann stattdessen gleich über die Elemente des `obj` iterieren. Ungetesteter Ersatz für die Schleife für die Ausgabe:

Code: Alles auswählen

ausgabe = list(header)
ausgabe.extend('%s\t\t%s' % (messwert, sum(row) / anzahl)
               for messwert, row in zip(messwerte, gesErgebnisse))
Und statt ``f.write(ausgabe)`` dann ``f.writelines(ausgabe)``. Ach und ich gehe davon aus, dass die Daten schon beim Einlesen in `float()`\s umgewandelt wurden.
Zizibee
User
Beiträge: 166
Registriert: Donnerstag 12. April 2007, 08:36

Montag 9. Juli 2007, 20:42

Vielleicht hab ich da mal wieder falsch nachgedacht, aber die Variable ausgabe wollte ich nicht als Liste anlegen, da ich in den Header in der Form
# blabla
# blabla2
und nicht so
[#blabla,
# blabla2]
brauche.
BlackJack

Montag 9. Juli 2007, 21:39

Das ist mir schon klar. Probier doch `file.writelines()` einfach mal aus.
Antworten