2016-11-16 4 views
1

Ich bin sehr neu in Python. Ich versuche, bestimmte Zeilen zu extrahieren, die Kopfzeilen zu überspringen, die in periodischem Intervall in einer Textdatei wiederholt werden und sie in einer anderen Datei aufschreiben. Ich konnte dies mit dem folgenden Code tun, aber das ist extrem langsam.Looping durch Datei, um Zeilen zu extrahieren

import random 
import sys 
import os 

with open('test.txt', encoding ='latin1') as rf: 
    with open('test1.txt', 'w') as wf: 
     for x, line in enumerate(rf): #reads the line number 
      #nskip = 3 #number of headers to skip 
      #nloop = 5 #number of loops in the file 
      ndata = 7 #number of lines in each loop 
      data = 4 #number of lines to be extracted 
      x+=1 
      #print(x,line) 

      for i in range(1,ndata+1): 
       for j in range((ndata*i - data)+1, ndata*i+1): 
        if x == j: 
         #print(line) 
         wf.write(line) 

z. von diesem Code kann ich Line5, Line6, Line7, Line12, Line13, Line14, Line19, Line20, Line21 bekommen (wenn Sie denken, dass die Testdatei Zeilen wie Line1, Line2, Line3 usw. für jede Zeile hat), also was ich vorhabe . Aber das Problem ist, meine reale Datei ist viel größer und es braucht viel Zeit und Speicher. Es muss einen schnelleren und pythonischen Weg geben, dies zu tun.

Auch ich mag in der Lage Loop-Nummer in Zeilen in jeder Schleife hinzufügen, dh 1. Schleife würde 1 in allen Linien (irgendwo in jeder Zeile, kann Line5 1, Line6 1, Line7 1, Line12 2, Line13 2, Line14 2, Line19 3 usw.). Was ich versuche, ist etwas komplizierter. Aber das sollte mir den Weg ebnen. Danke.

Antwort

2

Da die Header und Datensätze in festen Größen vorliegen, überspringe die Anzahl der Headerzeilen und schreibe die Anzahl der Datensatzzeilen wiederholt, bis das Ende der Datei erreicht ist.

n_header_lines = 25 
n_record_lines = 100 
page_num = 0 

with open('test.txt', encoding ='latin1') as rf, with open('test1.txt', 'w') as wf: 
    try: 
     while True: 
      page_num += 1 
      for _ in range(n_header_lines): 
       next(rf) 
      for line_num in range(1, n_record_lines + 1): 
       prefix = 'Line {:3d} {:3d} '.format(line_num, page_num) 
       wf.write(prefix + next(rf))) 
    except StopIteration: 
     pass 
+0

dies mit n_header_lines auf die Testdatei Versucht = 4 und n_record_lines = 3. Mit 7 Zeilen in jeder Schleife: Die löschte war Leitung 5, 7, 9, 15, 17, 19, 25, 27, 29 und so weiter ... Ich würde erwarten, dass die Zeilen 5,6,7,12,13,14,19,20,21 usw. sind. Also ist der Code nicht so hilfreich. Noch mehr Vorschläge? Danke für die Post. – Luck4u

+0

@ Luck4u: Dieses Überspringen jeder anderen Zeile würde anzeigen, dass Sie außerhalb der Aufrufe von 'next (rf)' über 'rf' iterieren. Stellen Sie sicher, dass Sie keinen Code wie 'für Zeile in RF:' haben. Denken Sie auch daran, dass jeder Aufruf von 'next (rf) 'eine Zeile verbraucht. Wenn Sie das zweimal innerhalb einer For-Schleife tun, wird es doppelt so schnell verbraucht. Was ich versuche zu sagen, ist das Konzept ist Sound, Ihre Umsetzung fehlt. Fügen Sie es Ihrer Frage hinzu, wenn Sie möchten, dass ich es mir anschaue. –

+0

Gerade die Frage bearbeitet. Ich hoffe, es macht jetzt mehr Sinn. Vielen Dank! – Luck4u