2016-04-20 5 views
-1

Wie würde ich gehen über den Druck der letzten Zeile in einer Textdatei, die etwa ist und etwa 4 Millionen Zeilen Text bestehend aus This is a line hat. Bisher habe ich:Wie würde ich die letzte Zeile in einer großen Textdatei drucken?

File.py

f = open("foo.txt","r+") 
datalist = [] 
for line in f: 
    datalist.append(line) 
print(datalist[-1]) 

Das einzige Problem, das ich mit meinem Code zu sehen ist, dass es viel Speicher verwendet. Ich habe Leute gehört, die os.lseek stattdessen verwenden, aber ich weiß nicht, wie man es einführt.

+2

Anruf 'tail' über einen' subprocess'? Es liest die Datei rückwärts. Das kann man nicht schlagen (außer es in Python neu zu implementieren). Bist du auf Linux? – jDo

+0

@jDo Leider nicht, ich bin auf Windows 10 –

+0

'print (" Dies ist eine Zeile ")'? Ich bin mir nicht sicher, wie ich Ihre Beschreibung des Eingabeformats wörtlich nehmen soll. – user2357112

Antwort

2

Wenn Sie nur die letzte Zeile benötigen, werfen Sie alles andere weg.

with open('foo.txt') as f: 
    for line in f: 
     pass 

# `line` is the last line of the file. 

Viel schneller (aber weit weniger lesbar) wäre am Ende der Datei zu starten und rückwärts von Bytes bewegen, bis Sie \n finden, dann lesen.

with open('foo.txt') as f: 
    fd = f.fileno() 
    os.lseek(fd, 0, os.SEEK_END) 
    while True: 
     ch = os.read(fd, 1) 
     if ch == b'\n': 
      line = f.read() 
      break 
     else: 
      os.lseek(fd, -2, os.SEEK_CUR) 

# `line` is the last line of the file 

Dies funktioniert, indem Sie die Datei vom Ende lesen, nach dem ersten Zeilenumbruch suchen und dann von dort weiterlesen.

+0

Wenn ich Ihren Code ausgeführt habe, habe ich 'TypeError: eine Ganzzahl ist erforderlich (hat Typ _io.TextIOWrapper)' –

+0

@Alex whoops, behoben. –

+1

Die Effizienz der Lese-Rückwärts-Lösung könnte verbessert werden, indem in Blöcken gesucht und gelesen wird und 'rfind' verwendet wird, um das letzte" \ n "zu finden. Auch die Handhabung von Zeilenumbrüchen als letztes Zeichen einer Datei ist eher subtil (der Code sucht bis zum Ende, liest nichts und geht dann zwei Zeichen zurück, wobei das letzte Zeichen der Datei übersprungen wird! Ich denke, das ergibt tatsächlich das richtige Ergebnis , aber es ist nicht auf den ersten Blick ersichtlich.) Idealerweise sollte es auch etwas Handhabung geben, wenn es nur eine Zeile gibt und Sie versuchen, die linke Seite der Datei zu suchen, oder wenn die Datei leer ist. – user2357112

0

Hier ist eine sehr einfache Verbesserung, die nur eine einzige Zeile zu einem Zeitpunkt speichert:

f = open("foo.txt","r") 
data = None 
for line in f: 
    data = line 
print(data) 

Oder Sie können die letzte Schleife Wert nach der Schleife abholen:

f = open("foo.txt","r") 
line = None 
for line in f: 
    pass 
print(line) 

Beachten Sie, dass in diesem Beispiel: line ist None, wenn die Datei leer ist (was der Grund für die anfängliche Zuweisung an line ist).

0

Eine schnelle Verbesserung wäre, nur datalist zu werfen und nur die letzte Zeile zu speichern, da das alles ist, was Sie interessieren.

f = open("foo.txt","r+") 
for line in f: 
    pass 
print(line) 

Ich könnte mir vorstellen, es gibt andere effizientere Möglichkeiten zu; Ich möchte nur eine anbieten, die eine direkte Ableitung Ihres Codes ist.

0

Sie müssen nicht jede Zeile an eine Liste anhängen. Verwenden Sie einfach die Schleifenvariable:

line = None # prevents a NameError if the file is empty 

with open("foo.txt", "r+") as f: 
    for line in f: 
     pass 
print(line) 
0

Check out deque im Sammlungen Modul. Es gibt ein Rezept, um die letzte 'n' Anzahl von Zeilen in einer Datei zu betrachten; d.h. Schwanz.

https://docs.python.org/2/library/collections.html#deque-recipes

def tail(filename, n=10): 
    'Return the last n lines of a file' 
    return deque(open(filename), n) 
+0

Dies scheint, als wäre es weit weniger leistungsfähig als OPs aktuelle Methode. –

Verwandte Themen