Seite 1 von 1
Nächste Zeile ausgeben lassen
Verfasst: Mittwoch 6. Mai 2015, 08:47
von trbo
Liebe Python Freund,
ich habe ein kleines Problem mit einem eigentlich doch sehr einfachen Programm. Ich durchsuche hier eine .txt Datei nach einem bestimmten Schlüssel und möchte mir die Zeile nach jener in der der Schlüssel gefunden wurde ausgeben lassen. Nachdem es nach ewigem rumprobieren jedoch immer noch nicht klappt hoffe ich hier auf Hilfe
hier mal der Code
Code: Alles auswählen
Journal=open('J_15April.txt')
jrn=Journal.read()
Zeile=jrn.split('14.04.2015')
for line in Zeile:
if 'BON' in line:
print(line)
Mfg
trbo
Re: Nächste Zeile ausgeben lassen
Verfasst: Mittwoch 6. Mai 2015, 09:05
von /me
Irgendwie sieht dein Ansatz merkwürdig aus. Was du
line nennst ist keine Zeile, sondern die Teile der Datei, die jeweils vor und nach deinem Suchbegriff '14.04.2015' stehen. Diese Teile können beliebig viele Zeilen umfassen. Eventuell ist deine Beschreibung auch unvollständig, dann müsstest du das noch einmal erklären.
Bei der Gelegenheit sollte man dann auch gleich dafür sorgen, dass die geöffnete Datei wieder geschlossen wird. Das geht entweder über ein explizites
close oder automatisch wenn du das with-Statement beim Öffnen verwendest.
Code: Alles auswählen
with open('J_15April.txt') as journal:
for line in journal:
if 'BON' in line:
print(next(journal))
Re: Nächste Zeile ausgeben lassen
Verfasst: Mittwoch 6. Mai 2015, 09:15
von mutetella
@trbo
1. Wenn Du eine Datei via dem
with statement öffnest, wird die Datei auch wieder ordnungsgemäß geschlossen, ohne dass Du Dich weiters darum kümmern musst.
2. Wenn Du die Datei mit `read()` einliest, bekommst Du deren gesamten Inhalt, was man nicht immer möchte und in Deinem Fall auch keinen Sinn macht, da Du ja eine bestimmte Zeile suchst. Ich würde also zu
`readline()` raten.
3. Nachdem man über
file objects direkt iterieren (Element für Element abrufen, im Falle einer Datei Zeile für Zeile) kann, kannst Du folgendes machen:
Code: Alles auswählen
with open('J_15April.txt') as journal:
for line in journal:
if 'BON' in line:
print(line)
mutetella
Re: Nächste Zeile ausgeben lassen
Verfasst: Mittwoch 6. Mai 2015, 09:19
von snafu
@mutetella: Gefragt war allerdings die *nachfolgende* Zeile.

Re: Nächste Zeile ausgeben lassen
Verfasst: Mittwoch 6. Mai 2015, 09:24
von mutetella
@snafu
Und ich wollte gerade nachhaken, was denn das `next()` da soll...
mutetella
Re: Nächste Zeile ausgeben lassen
Verfasst: Mittwoch 6. Mai 2015, 09:54
von nezzcarth
@me: Ich weiß nicht, ob das in der Datei vorkommt, aber für den speziellen Fall, dass das Schlüsselwort in zwei aufeinander folgenden Zeilen steht, würde dein Vorschlag glaube ich nicht das gewünschte(?) Ergebnis liefern. Vielleicht könnte man das mit einer Zustandsvariable lösen.
Re: Nächste Zeile ausgeben lassen
Verfasst: Mittwoch 6. Mai 2015, 10:14
von BlackJack
@nezzcarth: Das könnte man mit einer Funktion lösen die über ein ”Fenster” iteriert:
Code: Alles auswählen
#!/usr/bin/env python
from __future__ import absolute_import, division, print_function
from collections import deque
from itertools import islice
def iter_window(iterable, window_length):
items = iter(iterable)
window = deque(islice(items, window_length - 1), window_length)
for item in iterable:
window.append(item)
yield list(window)
def main():
with open('test.txt') as lines:
for line, next_line in iter_window(lines, 2):
if 'BON' in line:
print(next_line)
if __name__ == '__main__':
main()
Ist etwas komplexer als eine Zustandsvariable, dafür ist es universeller und wenn man die `iter_window()`-Funktion mal geschrieben hat kann man sie auch an anderer Stelle wiederverwenden.
Re: Nächste Zeile ausgeben lassen
Verfasst: Mittwoch 6. Mai 2015, 10:29
von snafu
Um mal diverse Eventualitäten abzudecken:
Code: Alles auswählen
from itertools import tee
def get_lines(infile, key):
line_iters = tee(infile)
try:
next(line_iters[1])
except StopIteration:
return
for line, next_line in zip(*line_iters):
if key in line:
yield next_line
def main():
with open('J_15April.txt') as infile:
lines = get_lines(infile, 'BON')
print('\n'.join(lines))
if __name__ == '__main__':
main()
Re: Nächste Zeile ausgeben lassen
Verfasst: Mittwoch 6. Mai 2015, 10:38
von BlackJack
@snafu: Das ist jetzt aber vom Ergebnis das gleiche wie die vier Zeilen von /me.
Re: Nächste Zeile ausgeben lassen
Verfasst: Mittwoch 6. Mai 2015, 10:41
von snafu
@BlackJack: Nein. Ich bezog mich vor allem auf den Einwand von nezzcarth, dass bei der simplen Lösung mit `next()` Zeilen übesprungen werden, wenn dass Schlüsselwort in zwei aufeinanderfolgenden Zeilen enthalten ist. Durch die Lösung mit zwei Iteratoren umgeht man dieses Problem. Außerdem schmeißt mein Code keine `StopIteration`, falls die Datei leer ist.
Re: Nächste Zeile ausgeben lassen
Verfasst: Mittwoch 6. Mai 2015, 15:11
von mutetella
@BlackJack
Müsste es, um nezzcarth's Einwand zu lösen, nicht
Code: Alles auswählen
...
if 'BON' in line and 'BON' not in next_line:
print(next_line)
heißen?
Ausgehend von einer Datei
erhalte ich ohne ``... not in ...``
als Ergebnis. Mit einem zusätzlichen ``... not in ...``:
mutetella
Re: Nächste Zeile ausgeben lassen
Verfasst: Mittwoch 6. Mai 2015, 15:48
von snafu
Es wäre auch interessant, was der Threadersteller eigentlich möchte. Vielleicht reicht ihm die von /me gezeigte Variante ja schon aus.
mutetella's Sichtweise des Problems geht ja schon mehr in Richtung State Machine. Das kann man zwar durchaus so implementieren, aber vielleicht wird es gar nicht in diesem Umfang benötigt...