2016-04-05 8 views
1

Ich versuche, bestimmte Zeilen von mehreren Dateien zu öffnen und die Zeilen jeder Datei zurückzugeben. Meine Lösung nimmt ziemlich viel Zeit in Anspruch. Hast du irgendwelche Vorschläge?
func.filename: der Name der angegebenen Datei
func.start_line: Ausgangspunkt in der angegebenen Datei
func.endline:Öffnen bestimmter Zeilen in mehreren Dateien

def method_open(func): 
    try: 
     body = open(func.filename).readlines()[func.start_line: 
               func.end_line] 
    except IOError: 
     body = [] 
     stderr.write("\nCouldn't open the referenced method inside {0}". 
        format(func.filename)) 
     stderr.flush() 
    return body 

Haben Sie daran, dass manchmal die Öffnung Datei func.filename kann Punkt in der angegebenen Datei Finishing sein die Gleiches aber leider ist das meistens nicht der Fall.

+0

Warum braucht es so viel Zeit? Ist die Datei sehr groß? Wenn ja, wie groß? –

+0

Sie können das [linecache] (https://docs.python.org/2/library/linecache.html) Modul oder 'itertools.islice' ausprobieren und sehen, ob sie auch zu zeitaufwendig sind. Sehen Sie mehr Details hier: http://stackoverflow.com/questions/2081836/reading-specific-lines-only-python –

+0

Nein, ich denke das Problem ist, dass ich die Datei immer wieder öffne und schließe, kann linecache stoßen Interessant wäre es, wenn es mehrere Zeilen gleichzeitig hätte. –

Antwort

2

Das Problem mit Readlines ist, dass es die gesamte Datei in den Speicher liest und Linecache tut das gleiche.

Sie können Zeit sparen, um eine Zeile zu einem Zeitpunkt, zu lesen und zu brechen die Schleife, sobald Sie func.endline

erreichen aber die beste Methode gefunden i itertools.islice

Hier die Ergebnisse zu verwenden, einige Tests, die ich auf einer 130MB-Datei ~ 9701k Linien getan haben:

--- 1.43700003624 seconds --- f_readlines 
--- 1.00099992752 seconds --- f_enumerate 
--- 1.1400001049 seconds --- f_linecache 
--- 0.0 seconds --- f_itertools_islice 

Hier können Sie das Skript I

import time 
import linecache 
import itertools 


def f_readlines(filename, start_line, endline): 
    with open(filename) as f: 
     f.readlines()[5000:10000] 


def f_enumerate(filename, start_line, endline): 
    result = [] 
    with open(filename) as f: 
     for i, line in enumerate(f): 
      if i in range(start_line, endline): 
       result.append(line) 
      if i > endline: 
       break 


def f_linecache(filename, start_line, endline): 
    result = [] 
    for n in range(start_line, endline): 
     result.append(linecache.getline(filename, n)) 


def f_itertools_islice(filename, start_line, endline): 
    result = [] 
    with open(filename) as f: 
     resultt = itertools.islice(f, start_line, endline) 
     for i in resultt: 
      result.append(i) 


def runtest(func_to_test): 
    filename = "testlongfile.txt" 
    start_line = 5000 
    endline = 10000 
    start_time = time.time() 
    func_to_test(filename, start_line, endline) 
    print("--- %s seconds --- %s" % ((time.time() - start_time),func_to_test.__name__)) 

runtest(f_readlines) 
runtest(f_enumerate) 
runtest(f_linecache) 
runtest(f_itertools_islice) 
verwendet finden
+0

interessant! Dies beantwortet meine Frage, welche Methode am schnellsten ist, im Gegensatz zu der erwähnten Frage: http://stackoverflow.com/questions/2081836/reading-specific-lines-only-python Vielen Dank! –