Nur jede dritte Zeile einlesen

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.
Kahnbein.Kai
User
Beiträge: 104
Registriert: Mittwoch 24. Juni 2015, 14:12
Wohnort: Bochum

Hallo,
ich habe ein kleines Problem mit Phyton. Ich möchte aus einer txt-Datei jede dritte Zeile einlesen und in eine neue txt-Datei schreiben lassen.
Die Textdatei sieht wie folgt aus.

Code: Alles auswählen

KS 111206               3474213.7725664153.008D  432.910L                       
KS 211206                                               431.600                 
KS 311206                                      L
KS 111265               3414250.6835956251.548D  427.210L                       
KS 211265                                               425.380                 
KS 311265                                      L
KS 111266               3474228.8334664655.748D  429.820L                       
KS 211266                                               425.140                 
KS 311266                                      L
KS 111258               3774210.88156743189.221D  429.180L                       
KS 211258                                               424.750                 
KS 311258                                      L
Es geht um die Zeile eins,vier, sieben und 10.

Ich habe mir folgendes überlegt. Phyton soll die Datei lesen und bei jeder Zeile gucken ob das 24 Zeichen ein String ist. Wenn ja soll er die Zeile in die neue Textdatei schreiben, wenn nicht die nächste Zeile lesen. Das habe ich mal versucht, leider klappt es nicht. Ist das überhaupt so möglich ?

Code: Alles auswählen

A=open("HOLL_GES.txt","r")
B=open("HOLL_GESB.txt","w")
for line in A:
    B.readlines()
    if str in txt[24]
        B.write()
    else

B.close()
A.close() 

Gruß Kai
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Was genau hast du denn versucht?
Das Programm ist ja an sich nicht lauffähig.

Variablen, wenn es keine Klassennamen sind, solltest du immer klein schreiben.

Was genau soll die Zeile 4 denn bewirken?

Zeile 5 macht so keinen Sinn. Was soll der in-Operator denn bewirken?

An sich kann dein Vorgehen so funktionieren. Du schaust dir jede Zeile an und entscheidest anhand von Merkmalen ob du sie auswählst oder nicht.
Länge einer Zeile, eine Zeichen an einer bestimmten Stelle oder überhaupt ein bestimmtes, enthaltenes Zeichen, könnten solche Merkmale sein.
BlackJack

@Kahnbein.Kai: Leider klappt das nicht ist eine schlechte Fehlerbeschreibung. Was klappt nicht? Was hast Du erwartet, und was passiert stattdessen? Gibt es eine Ausnahme, wenn ja, welche? Mit komplettem Traceback am besten.

Der Quelltext den Du zeigst ist nicht mal syntaktisch korrektes Python, also was hast Du tatsächlich laufen lassen?

Was hast Du Dir bei einem `readlines()`-Aufruf bei einer Datei in die *geschrieben* werden soll gedacht? Was denkst Du was der Ausdruck ``str in txt[24]`` macht und wie kommst Du darauf? Wo wird `txt` Deiner Meinung nach definiert?

Das sieht extrem nach hoffen das jemand eine Lösung für Dein Problem schreibt ohne das Du selber dafür etwas tun musst, denn der Quelltext sieht nach schnell zusammengeraten damit's ein bisschen wie Eigenleistung aussieht aus.

Jedes dritte Element aus einem iterierbaren Objekt, also zum Beispiel ein Dateiobjekt, kann man sehr leicht mit `itertools.islice()` bekommen. Wenn man die Eingabedatei komplett in den Speicher liest, dann kann man dafür die „slice syntax“ von Listen verwenden. Ungetestet:

Code: Alles auswählen

    with open('HOLL_GES.txt', 'r') as lines:
        with open('HOLL_GESB.txt', 'w') as out_file:
            out_file.writelines(islice(lines, 0, None, 3))
Kahnbein.Kai
User
Beiträge: 104
Registriert: Mittwoch 24. Juni 2015, 14:12
Wohnort: Bochum

Das Programm ist nicht lauffähig, die Syntax am str stimmt nicht.
Ich habe leider kein Beispiel für die if Abfrage gefunden, wie ich sie ausführen will. Deshalb weiß ich nicht wie ich das schreiben soll.

Das mit dem b.readlines() war ein versehen. Habe was Probiert und falsch zurück geändert. Ich habe es nochmal so versucht. Lauffähig ist es immer noch nicht.

Code: Alles auswählen

a=open("HALL_GES.txt","r")
b=open("HALL_GESB.txt","w")
for line in a:
    a.readlines()
    c=type(a[24])
    if c is class 'str':
        b.write()
    else
     
b.close()
a.close() 
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

In Zeile 3 beginnst du über alle Zeilen in der Datei a zu iterieren.
Was genau meinst du, macht Zeile 4?

Zeile 5 gibt dir immer den Typ eines einzelnen Zeichens aus einer Zeichenkette. Hier wird immer der Type der Zeichenkette das Ergebnis sein.

Wenn du feststellen willst, ob line[24] keine Zahl ist (ist es das was du versuchst?), dann versuche das a[24] nach int zu casten. Geht das schief, weißt du, dass es keine Zahl war.

Was macht das nackte else in Zeile 8?
Momentan gar nichts, außer dafür sorgen, dass dein Programm gar nicht startet.


Edit: Ich würde übrigens, weil ich ein fauler Mensch bin, wenn alle Zeilen so aussehen, einfach darauf testen ob ein "D" in der Zeile auftaucht. Dann muss nur sichergestellt sein, dass es in jeder Zeile, die du brauchst auftaucht und in keiner von denen, die du nicht brauchst. Zumindest hier im Beispiel wäre das aber der Fall.
Zuletzt geändert von sparrow am Dienstag 20. Oktober 2015, 12:39, insgesamt 1-mal geändert.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@Kahnbein.Kai: Dir fehlen offenbar wichtige Grundlagen. Entweder du hast schlichtweg noch zu wenig Programmiererfahrung oder du versuchst, auf Biegen und Brechen dir bekannte Konzepte aus einer anderen Sprache nach Python zu übertragen (wobei ein solches Vorgehen letztlich ebenfalls auf mangelnder Programmiererfahrung beruht). Daher die Frage: Hast du schonmal in einer anderen Sprache programmiert?
Kahnbein.Kai
User
Beiträge: 104
Registriert: Mittwoch 24. Juni 2015, 14:12
Wohnort: Bochum

Zeile 4 soll jede Zeile nacheinander einlesen.
Wenn bei der Überprüfung in Zeile 5 die Classe String rauskommt ist doch alles ok.
Soweit ich das verstanden habe, wandelt 'readlines()' die komplette Zeile in einen string um, ich will einfach schauen ob bei Position 24 ein Zeichen steht oder nicht.
Das else habe ich entfernt.
Nach dem D schauen ist auch eine gute Idee, aber leider weiß ich auch hier nicht wie ich das umsetzen soll.


@sanfu, nein habe ich nicht. Ich denke es sind eher die Grundlagen.
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Die Antwort darauf gibt es hier.

Das offizielle Tutorial zum Python lernen gibt es hier.
Zuletzt geändert von sparrow am Dienstag 20. Oktober 2015, 13:57, insgesamt 1-mal geändert.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

BlackJack hatte doch bereits eine einfache Lösung angegeben. Diese schreibt jede dritte Zeile aus der Quelldatei in die Zieldatei. Was spricht nun dagegen, sie anzuwenden?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Kahnbein.Kai hat geschrieben:Zeile 4 soll jede Zeile nacheinander einlesen.
Das soll es vielleicht, aber es liest die komplette Datei. Das zeilenweise Lesen hast du doch schon durch "for line in a:" realisiert.
Kahnbein.Kai hat geschrieben:Wenn bei der Überprüfung in Zeile 5 die Classe String rauskommt ist doch alles ok.
Dann kannst du die Prüfung auch weglassen. Das ist immer ein String, egal welches Zeichen sich dort befindet.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@Kahnbein.Kai
Neben der Lösung von BlackJack wäre eine weitere Möglichkeit, einen Zähler zu implementieren um damit die 0. und jede 3. Zeile "herauszufischen". Für den Zähler würde ich die built-in Funktion enumerate nutzen:

Code: Alles auswählen

>>> with open('HOLL_GES.txt') as file_:
...     for number, line in enumerate(file_):
...         print '{:2d}: {}'.format(number, line),
... 
 0: KS 111206               3474213.7725664153.008D  432.910L                      
 1: KS 211206                                               431.600                
 2: KS 311206                                      L
 3: KS 111265               3414250.6835956251.548D  427.210L                      
 4: KS 211265                                               425.380                
 5: KS 311265                                      L
 6: KS 111266               3474228.8334664655.748D  429.820L                      
 7: KS 211266                                               425.140                
 8: KS 311266                                      L
 9: KS 111258               3774210.88156743189.221D  429.180L                      
10: KS 211258                                               424.750                
11: KS 311258                                      L
Somit hast Du einmal die Zeilennummer (`number`) und auch gleich den Inhalt der Zeile (`line`). Mit dem modulo Operator prüfst Du dann, ob beim Teilen von `number` mit 3 ein Rest übrig bleibt. Wenn nicht, hast Du die gewünschte Zeile und schreibst diese in die Zieldatei:

Code: Alles auswählen

>>> bool(0 % 3)
False
>>> bool(1 % 3)
True
>>> bool(2 % 3)
True
>>> bool(3 % 3)
False
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Kahnbein.Kai
User
Beiträge: 104
Registriert: Mittwoch 24. Juni 2015, 14:12
Wohnort: Bochum

/me hat geschrieben: Das soll es vielleicht, aber es liest die komplette Datei. Das zeilenweise Lesen hast du doch schon durch "for line in a:" realisiert.
ok, dann habe ich das nicht verstaden. Ich dachte 'for line in a' ist eine Schleife die halt solange ausgeführt wird wie es in a Zeilen gibt.
/me hat geschrieben: Dann kannst du die Prüfung auch weglassen. Das ist immer ein String, egal welches Zeichen sich dort befindet.
Ok, das war wohl ein Denkfehler von mir.
snafu hat geschrieben:BlackJack hatte doch bereits eine einfache Lösung angegeben. Diese schreibt jede dritte Zeile aus der Quelldatei in die Zieldatei. Was spricht nun dagegen, sie anzuwenden?
Ja das ist richtig, ich wollte das mal auf meine Weise probieren.
Darauf wäre ich nämlich nicht gekommen.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Kahnbein.Kai hat geschrieben:Ich dachte 'for line in a' ist eine Schleife die halt solange ausgeführt wird wie es in a Zeilen gibt.
So ist es auch. Und bei jedem Schleifendurchlauf befindet sich der Inhalt der aktuellen Zeile in 'line'.

Code: Alles auswählen

with open('myfile.txt', 'r') as a:
    for line in a:
        print line
Kahnbein.Kai
User
Beiträge: 104
Registriert: Mittwoch 24. Juni 2015, 14:12
Wohnort: Bochum

Erstmal Danke Mutetella und BlackJack für die Lösungen.

@kbr
Den Unterscheid zwischen 'with open...' und 'a=open...' verstehe ich, laut dem Tutorial so das bei 'with open' die Datei wieder geschlossen wird desweiteren ist es kürzer als das try-Statment, was immer das auch ist.
Ich habe es noch "alten" Format, sprich mit 'a=open...'

Code: Alles auswählen

a=open("HALL_GES.txt","r")
b=open("HALLGESB.txt","w")

for line in a:
    c=type(line[24])
    if c is str:
        b.write()
b.close()
a.close()
TypeError: write() takes exactly 1 argument (0 given)

Gruß Kai
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@Kahnbein.Kai
Das ist ein wenig gruselig, was Du da versuchst... :wink: Wenn Du jede Zeile, die ein String ist, in die Zieldatei schreibst, dann schreibst Du jede Zeile dorthin. Eine Iteration über ein Fileobjekt liefert Dir Strings, genau genommen Bytes. Du hast also entweder die Möglichkeit, die Zeilen mitzuzählen oder aufgrund eines spezifischen Inhalts zu prüfen, ob die Zeile geschrieben werden soll, oder nicht.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Nochmal /me's Punkt: `line` ist immer ein String und da ein String in Python immer aus Strings besteht, ist auch `line[24]` immer ein String. Darum kannst du dir Zeile 5&6 sparen.

Wenn dir die Fehlermeldung tatsaechlich nichts sagt, dann ueberleg mal wie man beschreibt, was in `b` geschrieben wird ;)
Kahnbein.Kai
User
Beiträge: 104
Registriert: Mittwoch 24. Juni 2015, 14:12
Wohnort: Bochum

Ha es hat geklappt.
Danke Leute für eure geduldige Hilfe und Erklärungen.

Im 2.Semester hatte ich Phyton im Studium, ich werde die Vorlesungen incl. Übungen nochmal durcharbeiten und dann darauf aufbauen.


Gruß und einen schönen Abend noch


Kai

Hier ist noch der fertige Code

Code: Alles auswählen

a=open("HALL_GES.txt","r")
b=open("HALL_GESB.txt","w")
 

for line in a:
    c="D" in line
    if c is True:
        b.write(line)
b.close()
a.close()
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Kahnbein.Kai hat geschrieben:

Code: Alles auswählen

    c="D" in line
    if c is True:
        b.write(line)
Das kann man jetzt noch schöner schreiben.

Code: Alles auswählen

    if "D" in line:
        b.write(line)
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Übrigens heißt es Python, nicht Phyton.
In specifications, Murphy's Law supersedes Ohm's.
kodela
User
Beiträge: 185
Registriert: Montag 12. Oktober 2015, 21:24
Wohnort: Landsberg am Lech
Kontaktdaten:

Hallo,

damit müsste es mit jeder dritten Zeile funktionieren:

Code: Alles auswählen

        fin = open('test_Q.txt', 'r')
        fout = open('test_Z.txt', 'w')
        z = -1
        while 1:
            zeile = fin.readline()
            if zeile == "":
                break
            z += 1
            if z % 3 == 0:
                fout.write(zeile)
        fin.close
        fout.close()
MfG, kodela
Zuletzt geändert von kodela am Freitag 23. Oktober 2015, 15:25, insgesamt 1-mal geändert.
Antworten