Seite 1 von 1
Bestimmung der numberline innerhalb einer zip
Verfasst: Freitag 24. April 2020, 17:28
von aqualx
Hallo zusammen,
ich suche nach einer Möglichkeit die
numberline einer spezifischen Zeichenfolge innerhalb einer archivierten dat-Datei zu bestimmen.
Code: Alles auswählen
from zipfile import ZipFile
with ZipFile('archived_file.zip') as archive:
f = archive.open('folder/file.dat')
lines = f.readlines()[34:] # reading at the 34th line
Diese Zeichenfolge ist ein '***', die in der Testdatei in der 34. Zeile auftaucht. Nach der Zeichenfolge folgt eine Tabelle, die ich gerne in eine liste (später in ein dataframe) speichern würde.
Re: Bestimmung der numberline innerhalb einer zip
Verfasst: Freitag 24. April 2020, 20:37
von sparrow
Du brauchst dafür keine Zeilennummer.
Du iterierst über die Zeilen und schaust, ob du in der Zeile findest, was du suchst.
Dann iterierst du weiter und verarbeitest die kommenden Zeilen, bis etwas vorbei kommt, das das Ende der Tabelle kennzeichnet.
Re: Bestimmung der numberline innerhalb einer zip
Verfasst: Samstag 25. April 2020, 11:21
von aqualx
ich habs jetzt mit einer while-Schleife versucht in der ich alle Zeilen des Dokuments durchgehe und je das erste Zeichen teste.
Code: Alles auswählen
from zipfile import ZipFile
with ZipFile('testdatei.zip') as archive:
f = archive.open('Ordner/Datei.dat')
i = 0
stop = False
while (not stop):
line = f.readline()
i += 1
if (line[0] == '*'): stop = True
die Laufvariable i sollte demnach den Wert 34 bekommen. Leider ist dem nicht so. Wo liegt der Fehler?
Und wie kann ich nicht nur nach '*' suchen, sondern nach '***'?
Re: Bestimmung der numberline innerhalb einer zip
Verfasst: Samstag 25. April 2020, 12:49
von __blackjack__
@aqualx: Die Klammern um die Bedingungen gehören da nicht hin und man schreibt der lesbarkeit halber auch einzelne Zeilen in einem Block in eine eigene Zeile. `readline()` ist ineffizient, man iteriert direkt über die Zeilen des Dateiobjekts. Das man bitte nicht `f` nennt sondern `file` oder `lines`. Wenn man zusätzlich zu den Elementen eines iterierbaren Objekts noch eine laufende Zahl braucht, dann gibt es dafür die `enumerate()`-Funktion. Aber wozu brauchst Du überhaupt die Zahl?
Das `stop`-Flag ist überflüssig wenn man eine Endlosschleife schreibt, die an der entsprechenden Stelle mit `break` verlassen wird.
``line[0]`` kann einem auf die Füsse fallen wenn `line` eine leere Zeichenkette ist. Kann hier nicht passieren, aber mit das Problem kann man mit der `startswith()`-Methode umgehen. Was dann auch die Frage nach der Suche nach "***" beantworten sollte.
Was bekommst Du denn statt 34 für einen `i`-Wert? Und hast Du Dir `i` und ``line[0]`` denn einfach mal *in* der Schleife ausgeben lassen‽ Was erwartest Du da und in wie weit weichen die Ausgaben von Deinen Erwartungen ab?
Edit: Achtung, fehlerhaft:
Code: Alles auswählen
from zipfile import ZipFile
def main():
with ZipFile("testdatei.zip") as archive:
with archive.open("folder/file.dat") as lines:
i = None
for i, line in enumerate(lines):
if line.startswith("*"):
break
print(i)
if __name__ == "__main__":
main()
Hier wird dann eine Ausnahme ausgelöst die den Fehler in Deinem Programm zeigt. Basically:
Also entweder auf `bytes`-Ebene arbeiten, oder das `io`-Modul zur Hilfe nehmen.