Seite 1 von 1
IndexError: list index out of range
Verfasst: Montag 10. März 2008, 02:24
von kurvenschubser
Hallo zusammen,
nach langem Aufschieben möchte ich mich mal ein wenig mit Programmieren beschäftigen. Ich habe mir dazu das
http://www.galileocomputing.de/openbook/python/ Buch mal angeschaut, bekomme aber bei meinem kleinen Algorithmus dieses Problem:
Traceback (most recent call last):
File "/home/malte/software-schmiede/klauswert/src/klauswert.py", line 14, in <module>
notenkuerzeldict[zuordnung[0]] = zuordnung[1]
IndexError: list index out of range
Code: Alles auswählen
notenkuerzeldict = {} #Zum Referenzieren der Noten
dateiObj2 = open( "notenbezeichnungen.txt", "r" )
for line in dateiObj2:
line = line.strip()
zuordnung = line.split(" ")
notenkuerzeldict[zuordnung[0]] = zuordnung[1]
dateiObj2.close()
Die dazugehörige Datei notenbezeichnungen.txt hat keine letzte freie Zeile:
Code: Alles auswählen
1 1,0
2 1,3
3 1,7
4 2,0
5 2,3
6 2,7
7 3,0
8 3,3
9 3,7
10 4,0
11 5,0
Zuvor hab ich die Datei notenbezeichnungen schon einmal verwendet, so dass der Code so aussieht:
Code: Alles auswählen
dateiObj1 = open( "notenbezeichnungen.txt", "r" ) #Zur Ausgabe als Liste
notenkuerzel = dateiObj1.read()
dateiObj1.close()
notenkuerzeldict = {} #Zum Referenzieren der Noten
dateiObj2 = open( "notenbezeichnungen.txt", "r" )
for line in dateiObj2:
line = line.strip()
zuordnung = line.split(" ")
notenkuerzeldict[zuordnung[0]] = zuordnung[1]
dateiObj2.close()
Was ist das Problem? Bin dankbar für jeden Hinweis, hab auch schon recht viele Internetecken abgegrast auf der Suche nach Lösungen.
MfG
Verfasst: Montag 10. März 2008, 03:20
von audax
Da funktioniert eben das `split`nicht. Ein `split`an " " ist auch...ungaublich blöd.
Und das Buch ist auch doof, arbeite lieber das offizielle Tutorial auf python.org durch.
Tip zum debuggen:
Code: Alles auswählen
notenkuerzeldict = {} #Zum Referenzieren der Noten
dateiObj2 = open( "notenbezeichnungen.txt", "r" )
for line in dateiObj2:
line = line.strip()
zuordnung = line.split(" ")
try:
notenkuerzeldict[zuordnung[0]] = zuordnung[1]
except IndexError:
import pdb; pdb.set_trace
dateiObj2.close()
Dann wird der debugger gestartet, wenn der Index Error auftritt und du kannst dir das in Ruhe anschaun.
Btw:
http://www.python.org/dev/peps/pep-0008/
Dringend anschaun

Re: IndexError: list index out of range
Verfasst: Montag 10. März 2008, 11:13
von helduel
Moin,
kurvenschubser hat geschrieben:Was ist das Problem? Bin dankbar für jeden Hinweis, hab auch schon recht viele Internetecken abgegrast auf der Suche nach Lösungen.
du verlässt dich darauf, dass deine Daten mit vier Leerzeichen getrennt sind, was sie wohl nicht immer sind (im Gegensatz zu deinem Beispiel). Wenn in einer Zeile deine Daten mal mit weniger als vier Leerzeichen getrennt sind, dann trennt split nichts, sondern gibt dir eine Liste mit nur einem Eintrag zurück: die ganze Zeile. In deinem Code versuchst du auf den zweiten Eintrag in der Liste zuzugreifen (zuordnung[1]), den es hier aber nicht gibt. Deswegen der Index-Fehler.
Du könntest den Code robuster machen, indem du die Trennung mit einer Regex machst. Schau mal ins re-Modul.
Gruß,
Manuel
Re: IndexError: list index out of range
Verfasst: Montag 10. März 2008, 11:45
von gerold
Hallo kurvenschubser!
Willkommen im Python-Forum!
Du hast in deinem Textbeispiel in der vierten Zeile am Ende Leerzeichen dran hängen. Das merkt man, wenn man hier im Forum den Text mit der Maus markiert. audax hat es schon gezeigt: Falls sichergestellt ist, dass die Einträge IMMER mit vier Leerzeichen getrennt sind, dann genügt es, wenn du die unsichtbaren Zeichen vor und nach dem Text mit ``strip()`` löscht.
Code: Alles auswählen
for line in textfile:
line = line.strip()
if line:
kuerzel, note = line.split()
...
mfg
Gerold

Es läuft
Verfasst: Montag 10. März 2008, 15:35
von kurvenschubser
Danke für die Hinweise, ich hab die Liste auf Abstände mit 4 Leerzeichen getrimmt. Vorher wollte ich eigtl. den TAB als Separator, mit 4 Leerzeichen ist es aber ja sicherer. REs sind mir im Moment ein wenig kompliziert. Ich muss erstmal dei Basics hin bekommen...
MfG
Verfasst: Montag 10. März 2008, 15:50
von BlackJack
Nimm doch einfach nur ``line.split()`` ohne Argument. Das trennt an "whitespace" allgemein, also egal ob nun ein Leerzeichen, hunderte oder auch Tabs.
Habe ich gemacht
Verfasst: Montag 10. März 2008, 18:14
von kurvenschubser
Der Teil des Programms sieht nun so aus:
Code: Alles auswählen
notenkuerzeldict = {} #Zum Referenzieren der Noten
dateiObj2 = open("notenbezeichnungen.txt", "r")
for line in dateiObj2:
line = line.strip()
zuordnung = line.split()
notenkuerzeldict[zuordnung[0]] = zuordnung[1]
dateiObj2.close()
Mittlerweile macht das Ganze schon ein wenig mehr her, werde dann evtl. mal das Resultat im Forum posten
Danke für die Tips!
Verfasst: Montag 10. März 2008, 18:51
von Leonidas
Ich würde folgendes machen, statt:
lieber das und dann bist du die Indizes los.
(die Namen darfst du dir natürlich aussuchen)
Verfasst: Montag 10. März 2008, 20:26
von kurvenschubser
Ja das sieht ja auch ein wenig leserlicher aus
Verfasst: Montag 10. März 2008, 21:14
von BlackJack
Ist irgendwie noch ein bisschen lang. Ungetestet:
Code: Alles auswählen
datei = open('notenbezeichnungen.txt')
notenkuerzel = dict(zeile.split() for zeile in datei)
datei.close()
Verfasst: Dienstag 11. März 2008, 20:44
von kurvenschubser
BlackJack hat geschrieben:Ist irgendwie noch ein bisschen lang. Ungetestet:
Code: Alles auswählen
datei = open('notenbezeichnungen.txt')
notenkuerzel = dict(zeile.split() for zeile in datei)
datei.close()
Das klappt. Ist es performancetechnische besser solchen kurzen Code zu schreiben oder sollte man eher ausführlicher schreiben?
MfG
Verfasst: Dienstag 11. März 2008, 21:00
von Hyperion
kurvenschubser hat geschrieben:
Das klappt. Ist es performancetechnische besser solchen kurzen Code zu schreiben oder sollte man eher ausführlicher schreiben?
Naja, generell sollte es übersichtlich sein - und daraus resultiert ja i.A., dass man es kürzer schreibt.
Ausnahmen stellen dann eher Daten dar, die oft gebraucht werden und bei denen es aufwendig ist, diese dauernd neu zu berechnen. Da würde ich diese immer in eine Variable speichern und die Berechnung nur dann durchführen, wenn sich etwas ändert / ändern könnte.
Verfasst: Dienstag 11. März 2008, 21:43
von audax
Meiner Erfahrung ist der direkteste Code auch der schnellste. Bei dem Beispiel sollte es aber kaum einen Unterschied geben...
Eingebaute Loops (List Comprehensions, map, filter) sind generell fixer aber als explizite Schleifen und auch meist leichter verständlich.