Seite 1 von 1
Problem mit "list index out of range"
Verfasst: Dienstag 25. April 2006, 09:13
von keboo
Hallo Leute!
Durchblicke leider die Fehlermeldung nicht ganz:
Code: Alles auswählen
Traceback (most recent call last):
File "<pyshell#2>", line 2, in -toplevel-
if buffer[i].find('!') is not -1:
IndexError: list index out of range
Das kommt bei folgendem Skript zu Stande:
Code: Alles auswählen
for i in range(len(buffer)):
if buffer[i].find('!') is not -1:
buffer.remove(buffer[i])
if (buffer[i].find('<') is not -1):
buffer.remove(buffer[i])
Der Buffer sieht so aus:
- <DATA>
! comments
80.6 1.612 39.420 0.3120 1.5320 4.7300 [all info available] 0. 1.0
80.6 1.612 39.420 0.3120 1.5320 3.7300 [all info available] 0. 1.0
83.9 1.714 63.160 2.1369 1.3288 2.1336 [all info available] 0. 1.0
76.4 1.714 63.160 2.1369 1.3288 1.1336 [all info available] 0. 1.0
31.3 1.800 37.683 17.7897 0.7563 1.2997 [all info available] 0. 1.0
31.5 1.800 37.683 17.7897 0.7563 1.2997 [all info available] 0. 1.0
31.5 1.800 37.683 17.7897 0.7563 1.2997 [all info available] 0. 1.0
80.9 2.640 11.180 18.1656 1.0159 1.9906 [all info available] 0. 1.0
<_DATA>
Was stimmt in meiner FOR Schleife nicht?
Danke für eure Hilfe.
Johannes
Verfasst: Dienstag 25. April 2006, 09:31
von Rebecca
Du iterierst bis len(buffer), d.h. bis zur Bufferlaenge zu Beginn der for-Schleife. Aber zwischendurch loeschst due Elemente von buffer, d.h. buffer wird kuerzer, sodass buffer[Bufferlaenge zu Beginn der for-Schleife] nicht mehr existiert...
range(len(buffer)) passt sich ja zwischendurch nicht an.
Verfasst: Dienstag 25. April 2006, 09:41
von keboo
Hi!
Wie kann ich die FOR Bedingung sinnvollerweise anpassen?
Danke,
Johannes
Verfasst: Dienstag 25. April 2006, 09:59
von Buell
Hallo,
ich würde die for schleife sicheheitshalber in eine while schleife packen um nach jedem remove die Länge des buffer neu zu bestimmen, damit werden zwar alle bereits überprüften elemente von buffer noch einmal geprüft, was sicher kein guter Algorithmus ist, sollte aber solange buffer nicht soooo groß ist trotzdem in Ordnung sein.
in etwa so:
Code: Alles auswählen
run = True
while run:
for i in range(len(buffer)):
if buffer[i].find('!') is not -1:
buffer.remove(buffer[i])
break
else if (buffer[i].find('<') is not -1):
buffer.remove(buffer[i])
break
if i == range(len(buffer)):
run = False
break
möglichkeit 2:
das remove machst du in einer gesonderten for-schleife (bessere algorithmik)
Code: Alles auswählen
i_remove = []
for i in range(len(buffer)):
if buffer[i].find('!') is not -1:
i_remove.append(i)
else if (buffer[i].find('<') is not -1):
i_remove.append(i)
for j in i_remove:
buffer.remove(buffer[j])
kommt ganz drauf an was der rest des programmes macht...
Verfasst: Dienstag 25. April 2006, 10:10
von Mr_Snede
kennst du
schon?
Code: Alles auswählen
Puffer = [
"80.6 1.612 39.420 0.3120 1.5320 4.7300 [all info available] 0. 1.0",
"80.6 1.612 39.420 0.3120 1.5320 3.7300 [all info available] 0. 1.0",
"83.9 1.714 63.160 2.1369 1.3288 2.1336 [all info available] 0. 1.0",
"76.4 1.714 63.160 2.1369 1.3288 1.1336 [all info available] 0. 1.0",
"31.3 1.800 37.683 17.7897 0.7563 1.2997 [all info available] 0. 1.0"
]
for i, Zeile in enumerate(Puffer):
print "i: ", i,
print " Zeile: ", Zeile
# oder auch so:
for Zeile in enumerate(Puffer):
print " Zeile 2ter Durchlauf: ", Zeile
Ich bemühe mich nicht aus Listen etwas zu löschen , über die ich gerade iteriere.
Ich hätte an deiner Stelle gleich eine Funktion gebastelt (ist nur Pseudocode):
Code: Alles auswählen
def bla(Puffer):
rueckgabe_liste[]
for Spalte in enumerate(Puffer):
print " Spalte2ter Durchlauf: ", Spalte
if alles OK:
rueckgabe_liste.append(Spalte)
return rueckgabe_liste
Zeige bitte auch mal einen Puffereintrag, der deine if-Abfragen auslöst.
cu Sebastian
Verfasst: Dienstag 25. April 2006, 10:13
von keboo
Hi Buell!
Ich bekomme jetzt immer noch diese Fehlermeldung:
- Traceback (most recent call last):
File "C: DA\Source\skript.py", line 29, in -toplevel-
if buffer.find('!') is not -1:
IndexError: list index out of range
Wieso kann diese If Abfrage if buffer.find('!') is not -1: einen Fehler machen?
LG
Johannes
Verfasst: Dienstag 25. April 2006, 10:21
von Buell
die if abfrage an sich ist nicht das problem, die fehlermeldung sagt, dass deine Liste sozusagen zu Ende ist. Bsp: Liste hat 12 Elemente, so wäre das letzte Listenelement Liste[11] weil fängt ja bei 0 an und die for schleife versucht gerade auf zB Liste[12] zuzugreifen, was natürlich nicht vorhanden ist.
Probier mal folgendes:
mache wie im 1. bsp eine if abfrage (if i>=range(len(buffer))) in die for schleife und zwar an den Anfang der schleife (mit nem break drin)!!! Wenn das noch nicht funktioniert, dann verändere diese Abfrage so: if i>=range(len(buffer)) - 1
Verfasst: Dienstag 25. April 2006, 10:24
von keboo
Hallo Sebastian!
Was meinst du genau als Buffer-Eintrag:
Der Buffer kommt so zustande:
Code: Alles auswählen
buffer=[]
in_data = False
for line2 in file(input):
if "< DATA_ >" in line2:
in_data = True
line2 = line2[line2.find("< _DATA >")+9:]
if in_data:
buffer.append(line2)
if "< _DATA >" in line2:
break
Das Inputfile sieht so aus:
- <DATA>
! comments
80.6 1.612 39.420 0.3120 1.5320 4.7300 [all info available] 0. 1.0
80.6 1.612 39.420 0.3120 1.5320 3.7300 [all info available] 0. 1.0
83.9 1.714 63.160 2.1369 1.3288 2.1336 [all info available] 0. 1.0
76.4 1.714 63.160 2.1369 1.3288 1.1336 [all info available] 0. 1.0
31.3 1.800 37.683 17.7897 0.7563 1.2997 [all info available] 0. 1.0
31.5 1.800 37.683 17.7897 0.7563 1.2997 [all info available] 0. 1.0
31.5 1.800 37.683 17.7897 0.7563 1.2997 [all info available] 0. 1.0
80.9 2.640 11.180 18.1656 1.0159 1.9906 [all info available] 0. 1.0
<_DATA>
Wäre super, wenn du mir weiterhelfen könntest.
LG
Johannes
Verfasst: Dienstag 25. April 2006, 10:28
von Buell
...wenn ich das so sehe bin ich mir nicht so ganz sicher ob buffer der richtig gewählte bezeichner ist. Du erzeugst doch nur ne ganz normale Liste von Strings, wozu dann buffer?
Verfasst: Dienstag 25. April 2006, 10:35
von keboo
Hi Buell!
So gehts nicht. Hab anscheinend was nicht ganz verstanden von deiner Erklärung.
Code: Alles auswählen
while run:
for i in range(len(buffer)):
if i>=range(len(buffer)):
buffer.remove(buffer[i])
break
elif i>=range(len(buffer)):
buffer.remove(buffer[i])
break
if i == range(len(buffer)):
run = False
break
Kannst du das bitte anpassen, so wie du das gemeint hast.
Recht herzlichen Dank für deine Unterstützung,
Johannes
Verfasst: Dienstag 25. April 2006, 10:36
von keboo
Bin noch blutiger Anfänger. Habs mit den Bezeichnungen noch nicht so ganz. War offensichtlich eine falsche Bezeichnung. Sorry.
Verfasst: Dienstag 25. April 2006, 10:47
von Buell
gemeint hatte ich es etwa so:
Code: Alles auswählen
while run:
for i in range(len(buffer)):
if i>=range(len(buffer)):
run = False
break
if buffer[i].find('!') is not -1:
buffer.remove(buffer[i])
break
else if (buffer[i].find('<') is not -1):
buffer.remove(buffer[i])
break
wenn das nicht geht die Zeile:
durch das ersetzen:
wegen dem Bezeichner, bin mir nicht so sicher ob du wirklich einen Buffer benötigst, eigentlich könntest du auch jeden anderen Bezeichner verwenden um einfach eine Liste zu generieren. buffer ist ja ein Bezeichner für ein Buffer Object:
def:
Python objects implemented in C can export a group of functions called the ``buffer interface.'' These functions can be used by an object to expose its data in a raw, byte-oriented format. Clients of the object can use the buffer interface to access the object data directly, without needing to copy it first.
Two examples of objects that support the buffer interface are strings and arrays. The string object exposes the character contents in the buffer interface's byte-oriented form. An array can also expose its contents, but it should be noted that array elements may be multi-byte values.
An example user of the buffer interface is the file object's write() method. Any object that can export a series of bytes through the buffer interface can be written to a file. There are a number of format codes to PyArg_ParseTuple() that operate against an object's buffer interface, returning data from the target object.
More information on the buffer interface is provided in the section ``Buffer Object Structures'' (section 10.7), under the description for PyBufferProcs .
A ``buffer object'' is defined in the bufferobject.h header (included by Python.h). These objects look very similar to string objects at the Python programming level: they support slicing, indexing, concatenation, and some other standard string operations. However, their data can come from one of two sources: from a block of memory, or from another object which exports the buffer interface.
Buffer objects are useful as a way to expose the data from another object's buffer interface to the Python programmer. They can also be used as a zero-copy slicing mechanism. Using their ability to reference a block of memory, it is possible to expose any data to the Python programmer quite easily. The memory could be a large, constant array in a C extension, it could be a raw block of memory for manipulation before passing to an operating system library, or it could be used to pass around structured data in its native, in-memory format.
Verfasst: Dienstag 25. April 2006, 10:57
von keboo
Danke für deine ausführliche Antwort!
Irgendwie bekomm ich das einfach nicht zum Laufen. Bei der ersten Version kommt es anscheinend zu einer Endlosschleife.
Bei der zweiten Version bekomm ich diese Fehlermeldung:
Traceback (most recent call last):
File "C:\DA\Source\tabelle.py", line 30, in -toplevel-
if i>=range(len(buffer))-1:
TypeError: unsupported operand type(s) for -: 'list' and 'int'
Da passt was nicht.
Tut mir leid, dass ich mich so ungeschickt anstelle.
Danke nochmals,
Johannes
Verfasst: Dienstag 25. April 2006, 11:09
von Buell
...kein problem bin auch kein python guru
ja, fehlermeldung ist klar, man kann nicht einfach nen integer Wert von einem List-Operator abziehen ...
versuch mal so:
sonst ganz anders:
Code: Alles auswählen
j = 0
removes = []
for i in buffer:
if i.find('!') is not -1:
removes.append(j)
else if i.find('<') is not -1:
removes.append(j)
j += 1
for i in removes:
buffer.remove(buffer[i])
...sonst fällt mir nix mehr ein, außer buffer nicht so zu nennen
PS: mir fällt grad auf das obere von mir ist Blödsinn, ist ja das selbe wie if i == ...
Verfasst: Dienstag 25. April 2006, 12:19
von keboo
Hi Leute!
Irgendwie bekomm ich das nicht auf die Reihe:
Code: Alles auswählen
run=True
while run:
for i in range(len(buffer)):
if i < range(len(buffer)):
run = False
break
if buffer[i].find('!') is not -1:
buffer.remove(buffer[i])
break
if (buffer[i].find('<') is not -1):
buffer.remove(buffer[i])
break
Das Skript läuft, aber die Elemente der Liste in welchen '!' oder '<' vorkommen werden nicht gelöscht.
Woran liegt das?
Lg
Johannes
Verfasst: Dienstag 25. April 2006, 12:54
von keboo
Wie kann man das lösen, damit ich die Elemente aus meiner Liste gelöscht werden in welchen nicht '!' oder '<' vorkommt.
Wie kann da ein kurtzes Skript aussehen?
Danke,
Johannes
Verfasst: Dienstag 25. April 2006, 13:13
von keboo
Ich hatte gerade die Idee, dass Problem bereits beim Einlesen zu lösen.
Das Einleseskript sieht so aus:
Code: Alles auswählen
in_data=False
for line2 in file(input):
if "< DATA_ >" in line2:
in_data = True
line2 = line2[line2.find("< _DATA >")+9:]
if in_data:
buffer.append(line2)
if "< _DATA >" in line2:
break
Wie kann ich dieses Skript verändern, damit die Zeilen in welchen '!' und '<' vorkommen erst gar nicht eingelesen werden?
Danke,
Johannes