2013-06-07 10 views
5

ich eine Datei "test.txt" haben:Ist Datei-Objekt in Python ein iterable

this is 1st line 
this is 2nd line 
this is 3rd line 

der folgende Code

lines = open("test.txt", 'r') 
for line in lines: 
    print "loop 1:"+line 
for line in lines: 
    print "loop 2:"+line 

nur druckt:

loop 1:this is 1st line 

loop 1:this is 2nd line 

loop 1:this is 3rd line 

Es spielt keine‘ t print loop2 überhaupt.

Zwei Fragen:

  1. die Objektdatei von open() zurückgegeben, ist es ein iterable? deshalb kann es in einer for-Schleife verwendet werden?

  2. Warum wird loop2 überhaupt nicht gedruckt?

Antwort

24

Es ist nicht nur ein iterable, es ist ein Iterator, weshalb es nur die Datei einmal durchlaufen kann, ist. Sie können den Dateicursor mit .seek(0) zurücksetzen, wie viele vorgeschlagen haben, aber Sie sollten in den meisten Fällen nur einmal eine Datei iterieren.

+1

+1 für eine schöne, prägnante Beschreibung der iterierbaren vs-Iterator-Sache (die meisten der anderen Antworten nicht einmal versuchen, obwohl es der Schlüssel zu der Frage ist). – abarnert

+0

Danke für diese Beschreibung. – martinbshp

1

Sie sind bereits am Ende der Datei. Dateiobjekte sind Iteratoren. Sobald Sie über sie iterieren, sind Sie an der endgültigen Position. Das erneute Iterieren wird nicht von Anfang an beginnen. Wenn Sie wieder in der ersten Zeile beginnen möchten, müssen Sie lines.seek(0) verwenden.

+0

Das ist irreführend. 'List's sind auch iterierbar, und doch kann man sie ohne ein' seek' oder ähnliches wiederholen. Das Problem besteht darin, dass Dateiobjekte _iterators_ sind (und iterierbar sind). – abarnert

+0

Typo. Ich meinte Iterator. Vielen Dank. Fest. –

2

Ja, Dateiobjekte sind Iteratoren.

Wie alle Iteratoren können Sie nur durchlaufen, danach ist der Iterator erschöpft. Ihr Dateilesezeiger befindet sich am Ende der Datei. Öffnen Sie die Datei erneut, oder verwenden Sie .seek(0), um den Dateizeiger zurückzuspulen, wenn Sie ihn erneut durchlaufen müssen.

Alternativ versuchen Sie, eine Datei zweimal zu vermeiden. Extrahieren Sie während der ersten Schleife das, was Sie benötigen, in eine andere Datenstruktur (Liste, Wörterbuch, Gruppe, Heap usw.).

2

Ja, Dateiobjekte sind iterierbar, aber um zum Anfang der Datei zurückzukehren, müssen Sie lines.seek(0) verwenden, da Sie nach der ersten Schleife am Ende der Datei sind.

0

Es wäre jedoch besser, Code neu zu schreiben, so dass die Datei nicht zweimal durchlaufen werden muss. Lesen Sie alle Zeilen in eine Liste oder führen Sie die gesamte Verarbeitung in einer einzelnen Schleife aus.

Verwandte Themen