Python keywords suche!

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
Saga
User
Beiträge: 9
Registriert: Samstag 2. Juni 2018, 17:44

Start: Beispiel datei
...
Keyword/23
Zeile1
Zeile 2
Zeile 3 (ab hier müssen die zeilen kopiert werden)
...
...(bis hier müssen die zeilen kopiert werden)
#
...
...
Keyword/85
Zeile1
Zeile 2
Zeile 3
...
#
...

Ende: Beispiel datei

Ich will ein code erstellen, der nach einem keyword sucht und die zeilen danach speichert, ab der dritten zeile bis vor einem bestimmten symbol zbs. #
Der zeilen inhalt kann in einer liste gespeichert werden.
Saga
User
Beiträge: 9
Registriert: Samstag 2. Juni 2018, 17:44

Saga hat geschrieben: Samstag 2. Juni 2018, 17:48 Start: Beispiel datei
...
Keyword/23
Zeile1
Zeile 2
Zeile 3 (ab hier müssen die zeilen kopiert werden)
...
...(bis hier müssen die zeilen kopiert werden)
#
...
...
Keyword/85
Zeile1
Zeile 2
Zeile 3
...
#
...

Ende: Beispiel datei

Ich will ein code erstellen, der nach einem keyword sucht und die zeilen danach speichert, ab der dritten zeile bis vor einem bestimmten symbol zbs. #
Der zeilen inhalt kann in einer liste gespeichert werden.
Ich habe angefangen nach Reg. Expressions zu gucken, bin aber moch nicht fundig wie ich das angehen kann.
Freue mich auf euer Support/Hinweise.
Sirius3
User
Beiträge: 18266
Registriert: Sonntag 21. Oktober 2012, 17:20

Reguläre Ausdrücke brauchst Du auch nicht. Steht das Schlüsselwort alleine in einer Zeile, oder nur irgendwo in einer Zeile?
Saga
User
Beiträge: 9
Registriert: Samstag 2. Juni 2018, 17:44

Die schlüsselwörter stehen am anfang einer Zeile, gefolgt von „ /„ und einer zahl.
Sirius3
User
Beiträge: 18266
Registriert: Sonntag 21. Oktober 2012, 17:20

Dann reicht ja ›startswith‹, eine Schleife, eine Zustand (Suchen, Schlüsselwort gefunden, 1 Zeile danach, 2 Zeilen danach, Schreiben).
Saga
User
Beiträge: 9
Registriert: Samstag 2. Juni 2018, 17:44

Startswith sucht nach keyword und übergibt true wenn gefunden! Wie kann ich dann sagen, gehe 2 zeilen runter und kopiere in eine liste alle zeilen bis # gefunden ist. Die erzeugte liste soll eeiter gefüllt werden mit weiteren zeilen weil keyword mehrmals im text auftaucht!!
Sirius3
User
Beiträge: 18266
Registriert: Sonntag 21. Oktober 2012, 17:20

Was Du brauchst ist eine Schleife und einen Zustand, der sich ändert, je nach Bedingung. Was hast Du Dir schon überlegt, wie man das Problem lösen könnte?
Saga
User
Beiträge: 9
Registriert: Samstag 2. Juni 2018, 17:44

ich habe bisher dieses code erstellt:

############################################
infile = open('beispiel.txt','r')
copy = False
tmpLines = []
keyword_id = []
i=0
for line in infile:
if line.startswith('keyword/'):
id_th= line[8:-1]
keyword_id.append(id_th)
copy = True
elif line.startswith('#'):
copy = False

elif copy:
tmpLines.append(line)
########################################

keyword_id: gibt mir die Nummer vom keyword. funktioniert
tmpLines: gibt mir alle zeile zwischen keyword und #, ich will die ersten zwei zeilen nach keyword übersringen und erst dann die zeilen kopieren bis #.

wie kann ich das am besten machen?
Benutzeravatar
__blackjack__
User
Beiträge: 14032
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@saga: Du könntest entweder am Ende des Blocks die ersten beiden Elemente aus der Liste entfernen, oder aber am Anfang mit zwei `next()`-Aufrufen mit dem Dateiobjekt die nächsten zwei Zeilen überspringen.

`i` wird definiert aber nicht verwendet‽

Beim öffnen der Datei solltest Du mal die ``with``-Anweisung anschauen. Dann wird die Datei auch unter allen Umständen auch wieder geschlossen.

Namenskonvention für alles ausser Klassen und Konstanten ist `klein_mit_unterstrichen`. Der Präfix `tmp` macht hier auch nicht wirklich Sinn. Es geht nicht wirklich Information verloren wenn man den weg lässt.

Bei Sequenztypen wie Listen verwendet man üblicherweise den Plural des Namens der für ein Element passen würde. Also `keyword_ids`, denn das ist ja nicht eine ID sondern mehrere.

”Magische” Zahlen sollte man vermeiden. Entweder als Konstanten definieren, damit der Leser weiss was die Zahl bedeutet, oder aber von einem anderen Wert ableiten wenn sie davon abhängig ist. Bei der 8 habe ich nämlich den starken Verdacht, das die von der Länge des Schlüsselwortpräfixes abhängt.

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
from __future__ import absolute_import, division, print_function

KEYWORD_PREFIX = 'keyword/'

def main():
    with open('beispiel.txt', 'r') as in_file:
        keyword_ids = []
        lines = []
        copy = False
        for line in in_file:
            if line.startswith(KEYWORD_PREFIX):
                copy = True
                keyword_ids.append(line[len(KEYWORD_PREFIX):].rstrip())
                next(in_file)
                next(in_file)
            elif line.startswith('#'):
                copy = False
            elif copy:
                lines.append(line)
    print(keyword_ids)
    print(lines)


if __name__ == '__main__':
    main()
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Saga
User
Beiträge: 9
Registriert: Samstag 2. Juni 2018, 17:44

Danke blackjack.
Ich habe noch eine Frage bezüglich inhalt einer liste rausschreiben in text und zwar enthält die liste viele nummer, die ich in dem txt file in dieser weise anordnen will.
10 nummer pro zeile
(3xleerzeichen)nummer1(3xleerzeichen)nummer1....
Ich habe das mit probiert: {3xleerzeichen}.join(str(n) for n in (list))

Ich habe das mit maximal 10 elements pro zeile nicht rausgefunden..
Benutzeravatar
__blackjack__
User
Beiträge: 14032
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Da wirst Du einfach eine Schleife schreiben müssen die in jedem Durchlauf 10 Elemente als eine Zeile raus schreibt.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Saga
User
Beiträge: 9
Registriert: Samstag 2. Juni 2018, 17:44

ich habe das jetzt so gemacht aber leider noch nicht erfolgreich!!

with open('outfile.txt', 'w') as out_file:
i=0
out_file.write('Header\n')
for i in liste:
out_file.write(' '.join ( liste [ i : i+9 ] ) )
out_file.write('\n')
i+=9
Benutzeravatar
__blackjack__
User
Beiträge: 14032
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das `i=0` und das `i+=9` haben keinen Effekt, denn in der `for`-Schleife bekommt das `i` ja immer den nächsten Wert aus `liste` zugewiesen. Die Schleife darf nicht über `liste` gehen, sondern muss über passende Werte für `i` gehen. Also in 10er-Schritten (oder jetzt in 9er-Schritten?) von 0 bis zur Länge der Liste. Dazu gibt's die `range()`-Funktion (in Python 2 die `xrange()`-Funktion).
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Saga
User
Beiträge: 9
Registriert: Samstag 2. Juni 2018, 17:44

so jetzt etwas besser:

with open('outfile.txt', 'w') as out_file:
i=0
out_file.write('Header\n')
for element in liste :
out_file.write('<drei leerzeichen>'.join(liste[i:i+9]))
out_file.write('\n')
i+=9

es funktioniert so dass 10 elemente pro zeile ausgegeben werden. ich kriege auch die 3 leerzeichen zwischen den elementen bis auf die ersten elemente in der zeile.

ist-ausgabe:

element1+++element2+++element3.....

soll-ausgabe:

+++element1+++element2+++element3...

wie kriege ich das hin?
Saga
User
Beiträge: 9
Registriert: Samstag 2. Juni 2018, 17:44

ich habe das hingekriegt durch ersetzen

von :
out_file.write('<drei leerzeichen>'.join(liste[i:i+9]))

durch :
print('<drei leerzeichen>','<drei leerzeichen>'.join(liste[i:i+9]),file=out_file)
Sirius3
User
Beiträge: 18266
Registriert: Sonntag 21. Oktober 2012, 17:20

@Saga: wie __blackjack__ schon geschrieben hat, solltest Du nicht händisch einen Index zählen und dann noch mit der for-Schleife zu oft über die Elemente iterieren, sondern die for-Schleife über den Index mit range in 9er-Schritten laufen lassen.
Benutzeravatar
__blackjack__
User
Beiträge: 14032
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Saga: Das `for element in liste` ist falsch, da kommen viel zu viele Schleifendurchläufe zustande und am Ende der Datei Leerzeichen die dort nicht hingehören. Und das `print()` mit den zusätzlichen drei Leerzeichen gibt am Anfang *vier* Leezeichen aus. Die Zeichenkette bei `join()` ist ein Trenner *zwischen* Elementen. Das willst Du hier aber eigentlich gar nicht, denn Du möchtest einen Präfix vor jedem Element. Dann sollte man das auch so ausdrücken, sonst passt der Code nicht wirklich zur Absicht des Programmierers.

Was man alternativ auch machen könnte ist die Elemente einzeln ausgeben, mit `enumerate()` dafür sorgen, dass man zusätzlich eine laufende Zahl zu jedem Element bekommt und per Modulo-Operation ermittelt wann ein Zeilenendezeichen geschrieben werden soll.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Antworten