Seite 1 von 1
"for line in x:" verhaspelt sich?
Verfasst: Dienstag 28. Februar 2006, 17:43
von CM
Hoi,
habe gerade zwei Stunden tot geschlagen, weil sich ein Skript verhaspelt hat. Der Code sah so aus:
Irgendwann bricht Python die Prozessierung meiner Daten in dem File (Format: csv) einfach ab (immer an der selben, unauffälligen, Stelle).
Wenn ich aber schreibe:
funktioniert alles. (Bei xreadlines allerdings fliegt das Skript an der selben Stelle auf die Nase wie zuvor.)
Woran könnte das liegen? Jemand eine Idee?
Gruß,
Christian
Verfasst: Dienstag 28. Februar 2006, 18:25
von modelnine
Ja. Du veränderst den Filepointer in der Schleife, denn mit readlines() werden Zeilen alle direkt beim Laden gelesen, während mit xreadlines() und for l in f die Zeilen der Reihe nach gelesen werden, und zwar immer ab dem aktuellen Filepointer, aus dem Iterator.
Das ist wieder ein typischer Fall von "wir verändern das Objekt über das wir iterieren in der Schleife." Und das geht bei fast keinem Typ gut aus.
Verfasst: Mittwoch 1. März 2006, 13:04
von CM
Danke. Hm, es klingt plausibel. Hätte ich also eine Kopie von line vor allem weiteren Schritten anlegen müssen, um dann mein .split() darauf anzuwenden ...
Gruß,
Christian
Verfasst: Mittwoch 1. März 2006, 13:50
von mr.hide
Hmmm, sehe ich das richtig, dass es prinzipiel möglich ist, direkt über das file zu iterieren?
Und der Fehler liegt dann daran, dass du in der Schleife etwas machst...?
Weil bei extrem großen Files ist es doch net so gut wenn man die komplett in eine Liste lädt...
Verfasst: Mittwoch 1. März 2006, 13:57
von rayo
Hi
Also was ist denn rU?
Code: Alles auswählen
f = open(fname,'r')
for line in f:
l = line.split()
print l
Sowas sollte ohne Probleme funktionieren.
Gruss
Verfasst: Mittwoch 1. März 2006, 14:27
von mawe
rayo hat geschrieben:
Also was ist denn ru?
pydoc hat geschrieben:
Add a 'U' to mode to open the file for input with universal newline support.
Verfasst: Mittwoch 1. März 2006, 14:41
von jens
mr.hide hat geschrieben:Weil bei extrem großen Files ist es doch net so gut wenn man die komplett in eine Liste lädt...
Stimmt... Würde mann dann nicht mit einer temp-Datei arbeiten? Oder die Original-Datei nach *.bak umbenennen, öffnen, iterieren, verändern und in neuer Datei schreiben...
Verfasst: Mittwoch 1. März 2006, 14:49
von rayo
Aber sollte das rU nicht ein String sein?
Und was passiert ohne U? (nur r)
Gruss
Verfasst: Mittwoch 1. März 2006, 14:51
von jens
Jep, es sollte ein String sein... Da ist ist der Code aus dem ersten Beitrag broken
Ohne das "U" sind IMHO die Zeilenenden so wie in der Datei, somit sind nicht alle Varianten nach "\n" konvertiert...
Verfasst: Mittwoch 1. März 2006, 14:56
von CM
oh Gott, habe ich jetzt eine Grundsatzdiskussion auf dem Gewissen?
Natürlich ist es nicht so clever
extrem große Dateien einzulesen, aber das ist hier nicht der Fall und es kratzt mich überhaupt nicht, daß ich
nicht mit Kanonen auf Spatzen schießen muß ...
ad "rU": Das habe ich mir angewöhnt, weil immer wieder mal unter Windows genierierte Dateien auf meinem Rechner (Linux) landen.
ad rayos Bemerkung:
Sowas sollte ohne Probleme funktionieren.
Tja, das habe ich eben auch gedacht. Und das hat es auch immer getan - nur jetzt eben nicht. modelnine hat wohl den entscheidenden Hinweis gegeben: Irgendwo mache ich etwas mit "line", was ich nicht sollte - ungewollt, nota bene. Aber bevor ich diese Stelle jetzt gefunden und korrigiert habe ...
Gruß,
Christian
Verfasst: Mittwoch 1. März 2006, 14:57
von rayo
Vielleicht liegt ja genau beim U das Problem, einfach mal testen, weil bis jetzt hatte ich nie Probleme eine Datei direkt mit for line in f: zu bearbeiten
gruss
*edit* Also line ist ja ein String und die sind unveränderbar, also darfst du mit dem machen was du willst, da sollte nichts passieren.
funktioniert denn:
Code: Alles auswählen
f = open(fName, 'rU')
for line in f:
print line.split(' ')
f.close()
Verfasst: Mittwoch 1. März 2006, 15:10
von gerold
modelnine hat geschrieben:Das ist wieder ein typischer Fall von "wir verändern das Objekt über das wir iterieren in der Schleife." Und das geht bei fast keinem Typ gut aus.
Hi!
Wurde die Datei wirklich mit
geöffnet (sieht man von den fehlenden Anführungszeichen ab), dann ist die Datei "readonly". Zumindest kann dann dieses "File"-Objekt nicht für eine Änderung herangezogen werden. Egal was du mit diesem File-Objekt anstellst, es dürfte sich nicht verändern.
Anders sieht das natürlich aus, wenn du die Datei nicht mit "rU" öffnest und mit "write()" an das Ding ran gehst. Auch eine Änderung von einem anderen Programm aus ist nicht auszuschließen.
@CM: Kann es sein, dass sich die Datei in der Zwischenzeit ändert, oder ist das ausgeschlossen?
lg
Gerold

Verfasst: Mittwoch 1. März 2006, 16:16
von CM
Ja, es ist ausgeschlossen, daß die Datei in der Laufzeit des Skriptes geändert wird. Aber ansonsten sind Deine Einwände natürlich absolut richtig.
Aber ich werde mich erst wieder damit befassen, wenn ich etwas mehr Zeit habe - zur Zeit kommt mir mein Chef zu häufig mit "machen Sie doch mal schnell" ...
Gruß,
Christian
Verfasst: Mittwoch 1. März 2006, 21:58
von BlackJack
gerold hat geschrieben:Wurde die Datei wirklich mit
geöffnet (sieht man von den fehlenden Anführungszeichen ab), dann ist die Datei "readonly". Zumindest kann dann dieses "File"-Objekt nicht für eine Änderung herangezogen werden. Egal was du mit diesem File-Objekt anstellst, es dürfte sich nicht verändern.
Ganz egal ist das nicht. Wenn Du in einer Schleife über `f` iterierst, dann darfst Du innerhalb der Schleife aus `f` auch nichts lesen! Der Iterator über die Zeilen puffert nämlich und wenn Du dann innerhalb der Schleife liest, dann ist das nicht die nächste Zeile nach `line` sondern kann eine spätere Zeile, oder auch nur ein Teil (das Ende) davon sein.
Verfasst: Mittwoch 1. März 2006, 22:15
von gerold
BlackJack hat geschrieben:gerold hat geschrieben:Wurde die Datei wirklich mit
geöffnet (sieht man von den fehlenden Anführungszeichen ab), dann ist die Datei "readonly". Zumindest kann dann dieses "File"-Objekt nicht für eine Änderung herangezogen werden. Egal was du mit diesem File-Objekt anstellst, es dürfte sich nicht verändern.
Ganz egal ist das nicht. Wenn Du in einer Schleife über `f` iterierst, dann darfst Du innerhalb der Schleife aus `f` auch nichts lesen! Der Iterator über die Zeilen puffert nämlich und wenn Du dann innerhalb der Schleife liest, dann ist das nicht die nächste Zeile nach `line` sondern kann eine spätere Zeile, oder auch nur ein Teil (das Ende) davon sein.
Hi BlackJack!
Ich habe das jetzt mal ohne Kürzung oben stehen lassen. --

Dir ist schon klar, dass ich kein Wort verstanden habe, oder?
Der einzige Grund, weshalb ich mit
über ein File-Objekt iterieren möchte ist, dass ich Zeile für Zeile lesen möchte. Jetzt sagst du mir, dass man das nicht darf. Ich bin jetzt ein wenig -- nein stimmt nicht -- total verwirrt.
Ich weiß, dass du das nicht so gemeint hast, aber schlau werde ich daraus trotzdem nicht.
lg
Gerold

Verfasst: Mittwoch 1. März 2006, 23:18
von modelnine
Was ich in meinem ursprünglichen Post sagte und was jetzt auch wieder gemeint wurde:
ist böse, weil ich innerhalb der Schleife das Objekt
über das ich iteriere (also f) verändere.
ist nicht böse, weil ich das Objekt
über das ich iteriere in der Schleife nicht verändere.
Vergleiche mit:
Code: Alles auswählen
l = ["blah","blubb","gaga"]
for pos, item in enumerate(l):
print pos, item
del l[pos]
print l
Auch hier ändere ich wieder das Objekt
über das ich iteriere, und auch hier passieren böse Dinge.
Alles klar?
