Python; For-Schleife funktioniert nicht;

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
pyMill
User
Beiträge: 5
Registriert: Freitag 19. September 2014, 18:24

Hallo,

hier ist mein Quellcode:

Code: Alles auswählen

#This Python file uses the following encoding: utf-8

'''D:/Downloads/Eclipse/eclipse/workspace/CoreTemp/src/ExtractData.py'''

import csv

if __name__=='__main__':
    
    try:
        f = open('CT-Log 2014-09-18 13-36-52.csv')
        csvFile = csv.reader(f)
        csvExtracted = []
        i = 0
        for line in csvFile:
            pass
        #Printing the list
        for line in csvFile:
            for el in line:
                print(el,end=' ')
            print()  #newline
            #print(line)
            
            
    finally:
        f.close()
Der Code soll eine CSV-Datei öffnen und zum Beispiel alle leeren Zeilen und Einträge entfernen. Dazu brauche ich zwei For-Schleifen..
Wenn ich den Code jetzt so ausführe wie er da steht. bekomme ich kein Ergebnis in der Konsole ausgegeben, obwohl 'csvFile' nicht leer ist. Falls ich aber die For-Schleife in Zeile 14-15 auskommentiere, funktioniert die Schleife in Zeile 17 - 21 so wie sie soll. Ich versteh nicht woran das liegt..
Vielleicht kann mir jemand dabei weiterhelfen. Ich wäre jedenfalls sehr dankbar.

Viele Grüße,
pyMill
BlackJack

@pyMill: Wenn Du einmal über die Datei iteriert bist, dann ist der Dateizeiger am Ende der Datei und jeder weitere Leseversuch liefert nichts, weshalb die zweite Schleife sofort das Ende der Datei erkennt. Du müsstest die Datei erneut öffnen und wieder einen `reader()` erstellen. Wobei ich nicht verstehe warum Du die Datei zweimal durchgehen möchtest.

Normalerweise würde man das so angehen, dass man die alte Datei zum Lesen öffnet, eine neue zum Schreiben, und dann Datensatz für Datensatz durchgeht und entscheidet ob man den in die neue Datei schreibt oder eben auch nicht.
pyMill
User
Beiträge: 5
Registriert: Freitag 19. September 2014, 18:24

@BlackJack: Danke für die schnelle Antwort.
Ich habe mir schon gedacht, dass es an sowas liegen würde. Ich dachte for .. in .. würde immer ein Zeiger auf das erste Element liefern und dann erst durchiterieren..
BlackJack

@pyMill: Iteratoren kennen als einzige Operation „gib mir das nächste Element” (`next()`). So ein zurücksetzen könnte man theoretisch auf iterierbaren Objekten für die „gib mir einen Iterator”-Operation (`iter()`) implementieren, das macht aber keiner, und darum erwartet dieses Verhalten auch niemand. Bei Dateien ginge das auch nicht grundsätzlich weil nicht jedes Dateiobjekt ”seekable” ist, man also nicht bei jedem Dateiobjekt den Zeiger auch wieder auf den Anfang der Datei setzen kann. Ein Grund warum man das auch eher nicht explizit selber machen sollte zwischen den beiden Schleifen.
pyMill
User
Beiträge: 5
Registriert: Freitag 19. September 2014, 18:24

@BlackJack: Naja gewöhnliche Listen kann man ja mehrmals durchlaufen, ohne sich um das Zurücksetzen von Zeigern zu kümmern oder neue Listen zu erzeugen. Deswegen ist das Verhalten von Python in diesem Fall auch sehr unintuitiv, zumindest für mich. Trotzdem danke für deine Antworten!
BlackJack

@pyMill: Eine Liste ist kein Iterator sondern „nur” iterierbar. Eine Datei dagegen ist ein Iterator. Und die „gib mir einen Iterator”-Operation auf Iteratoren gibt per Konvention den Iterator selbst, unverändert zurück. Würde sich da jemand nicht dran halten, würde eine Menge Code kaputt gehen der sich darauf verlässt, dass man mit Iteratoren beliebig oft `iter()` aufrufen kann ohne das sich etwas am Zustand des Iterators ändert.
sfx2k
User
Beiträge: 54
Registriert: Dienstag 2. September 2014, 13:29

@pyMill
Die Dateiöffnungsroutine sollte sich ausserhalb des try-finally-Blocks befinden.
Du kannst eine Tür auch erst schließen, wenn Du sie vorher geöffnet hast ;)
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Noch besser wenn man direkt `with` benutzt und `try ... finally` ganz weglaesst :)
pyMill
User
Beiträge: 5
Registriert: Freitag 19. September 2014, 18:24

@sfx2k: Mich hat das Problem mit der for-Schleife am meisten gestört, deswegen habe ich mich um den Rest nicht so sehr gekümmert. Kann sein, dass du Recht hast, aber wenn ich eine Exception auffangen will, dann brauch ich den try Block.. Wahrscheinlich wäre hier ein try-catch-Block angemessener.

@cofi: Explizit wäre mir aber lieber als implizit. :-)
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

pyMill hat geschrieben:@cofi: Explizit wäre mir aber lieber als implizit. :-)
Das ist nicht der richtige Zeitpunkt, um mit Zitaten zu schmeissen.

Wie du schon richtig angemerkt hast, brauchst du zusaetzlich evtl noch ein `try/catch` fuer die `open` Exception _und_ `with` drueckt genau das aus, was du mit `try/finally` umschreibst: "Ich habe einen Block, an dessen Anfang und Ende etwas ausgefuehrt werden soll".

Noch dazu weiss das Objekt das in dem Fall sogar besser und du koenntest in `finally` Block etwas vergessen.
pyMill
User
Beiträge: 5
Registriert: Freitag 19. September 2014, 18:24

@cofi: Danke für den Hinweis mit dem "with". Ich habe nicht genau verstanden was es macht, deswegen bleibe ich für den Moment lieber bei den "try-catch"-Blöcken oder "try-except" wie es in Python heißt.
Hier finden sich mehr Informationen zu dem "with"-Block, der aber meines Wissens nach in anderen Programmiersprachen eine andere Bedeutung hat (man darf es ja den Leuten, die nicht mit Python aufgewachsen sind, bloß nicht zu einfach machen):

http://legacy.python.org/dev/peps/pep-0343/

Das eigentlich Thema war ja, warum die For-Schleife in Zeile 17-18 nicht funktioniert. Das Problem liegt daran, "csvFile" kein Container-Objekt ist, sondern ein Iterator-Objekt, das mir gerade nicht bei jedem Durchlauf einen neuen Zeiger auf das erste Element liefert, was auch BlackJack schon erklärt hat. Und dazu habe ich hier nochmal einen Link gefunden:

https://docs.python.org/3.1/glossary.html#term-iterator
BlackJack

@pyMill: Du meinst ``try``/``finally`` statt ``try``/``except``. Bei ``with`` weiss das Objekt um das es geht was beim Eintritt und beim Verlassen des Blocks zu tun ist. Bei ``try``/``finally`` musst Du das wissen und auch hinschreiben.

Ja es gibt andere Sprachen die das Schlüsselwort ``with`` für etwas anderes verwenden. Es gibt auch Sprachen die ``class`` für ein anderes Objektmodell verwenden als Python. Und es gibt Sprachen die ``with`` verwenden und auch ein ``using`` kennen was Python's ``with`` entspricht. Dafür gibt es dann wieder andere Sprachen die ``using`` für etwas ganz anderes verwenden. So was aber auch. Da legen die Sprachentwickler einfach so die Bedeutung von Schlüsselwörtern in ihrer jeweiligen Programmierprache fest wie sie denken das es passend ist. Sollte verboten werden so etwas. Wir brauchen ganz dringend eine Einheitssprache damit alle alles gleich machen. :twisted:
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

pyMill hat geschrieben:@cofi: Danke für den Hinweis mit dem "with". Ich habe nicht genau verstanden was es macht, deswegen bleibe ich für den Moment lieber bei den "try-catch"-Blöcken oder "try-except" wie es in Python heißt.
Hier finden sich mehr Informationen zu dem "with"-Block, der aber meines Wissens nach in anderen Programmiersprachen eine andere Bedeutung hat (man darf es ja den Leuten, die nicht mit Python aufgewachsen sind, bloß nicht zu einfach machen)
Hö? Aus Scheme kenne ich Funktionen/Makros deren Name mit ``with-`` beginnt mit ganz ähnlicher Semantik wie in Python: dass etwas Setup-Code ausgeführt wird, dann der Code der der Funktion übergeben wurde und dann kommt eventuell noch Teardown-Code. Also ganz ähnlich wie in Python Context Manager das mit ``__enter__`` und ``__exit__`` machen. Ist also quasi keinerlei Umdenken nötig :K
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Und dann noch diese Verwirrung mit den geschweiften Klammern. Die erzeugen einfach so Dictionaries und Mengen, dafür aber keine Blöcke. Überhaupt ist die Blockbildung mit Einrückung keine gute Idee. :mrgreen: Warum hat sich C dabei eigentlich nicht an den BEGIN-END-Standard gehalten ...?
Das Leben ist wie ein Tennisball.
BlackJack

Ich verstehe auch überhaupt nicht warum sich Forth's Bedeutung von THEN nicht durchgesetzt hat. :-)
Antworten