2016-11-15 4 views
0

Ich versuche, eine Aufgabe auszuführen, wo das Programm ein Verzeichnis durchläuft, jede Datei nacheinander öffnet und eine bestimmte Zeile vor allem anderen prüft. Wenn die Zeile ein bestimmtes Kriterium erfüllt (dh sie stimmt nicht mit dieser Zeile in einer anderen Datei im Verzeichnis überein), wird die Datei geschlossen und das Programm wird in die nächste Datei verschoben.Python - Schließen einer Datei, wenn sie eine Bedingung erfüllt

aps = [] 

import os 
for filename in os.listdir("C:\..."): 
    f = open(filename,"r") 
    (f.readline()) 
    (f.readline()) 
    ap = (f.readline()) 
    ap = ap.rstrip("\n") 
    aps.append(ap) 
    freqs = {} 
    for ap in aps: 
     freqs[ap] = freqs.get(ap, 0) + 1 
    for k, v in freqs.items(): 
     if v == 2: 
      f.close() 
     else: 

Für den ‚else:‘ ich ursprünglich versucht ‚f.seek (0)‘, bekamen aber den Fehler von Python nicht in der Lage zu sein mit einer geschlossenen Datei zu arbeiten. Ich habe dann 'f = open (Dateiname, "r") erneut versucht, aber das macht etwas Seltsames, wenn ich versuche, die erste Zeile mit dieser Methode zu drucken, sendet es auf eine verrückte Schleife und druckt die Zeile mehrmals.

Ist dies der beste Weg, um diese Aufgabe zu erledigen? Und wenn nicht, wie könnte ich es zur Arbeit bringen?

Vielen Dank.

+0

Was ist der Zweck des 'else'-Zweigs unten nach dem' f.close'?Müssen Sie noch aus der Datei lesen? – sal

+0

Sie sollten nach dem Schließen der Datei eine 'Pause' hinzufügen, damit die Schleife nicht fortgesetzt wird. –

Antwort

2

Schließen Sie die Datei nicht bedingt. Tun Sie, was Sie mit der geöffneten Datei tun müssen, und schließen Sie sie am Ende. Mit einem with Konstrukt wird die Datei automatisch schließen:

for filename in os.listdir(path): 
    with open(filename) as f: 
     # do processing here 
     if positive_condition: 
      # do more processing 
1

Hier ist, warum Ihr Code fehlschlägt. Sie initialisieren die aps-Liste außerhalb Ihrer äußeren for-Schleife, so dass es die angegebene Zeile aus allen Dateien enthält, die Sie überschleifen. Dann wird Ihr freqs Wörterbuch für jede Datei, die Sie öffnen, auf leer zurückgesetzt.

Also diese Zeilen:

for ap in aps: 
    freqs[ap] = freqs.get(ap, 0) + 1 

Schleife über jede Zeile, die bisher gelesen wurde, und die Frequenz zählen. Das Problem kommt in der inneren for-Schleife:

for k, v in freqs.items(): 
    if v == 2: 
     f.close() 

Was hier passiert, ist, dass freqs eine Reihe von Tasten hat möglicherweise so groß wie die Anzahl der Dateien, die Sie bisher über geschlungen haben, und Sie durch die einzelnen Schlüssel sind Looping. Wenn also zum ersten Mal ein Schlüssel den Wert 2 hat, wird die aktuelle Datei geschlossen. Aber dann wird die Schleife fortgesetzt, so dass python beim nächsten Mal, wenn ein Schlüssel den Wert 2 hat, versucht, die Datei zu schließen, aber sie ist bereits geschlossen.

Die einfachste Lösung ist eine break nach der f.close() hinzuzufügen. Aber es gibt bessere Möglichkeiten, diesen Code zu strukturieren.

Eine ist immer eine Datei mit einem with Befehl zu öffnen, es sei denn, Sie haben einen guten Grund, etwas anderes zu tun. Also:

with open(filename,"r") as f: 
    #code 

Auf diese Weise wird die Datei automatisch geschlossen, wenn Sie damit fertig sind.

Ich gehe davon aus, dass die Reihenfolge, in der Sie die Dateien durchlaufen, nicht wichtig ist und dass der Häufigkeitstest alle Dateien einschließen soll, nicht nur die, die bisher geöffnet wurden. In diesem Fall kann es einfacher sein, zweimal durchzulaufen, einmal, um das Frequenzdikt zusammenzustellen, und ein zweites Mal, um zu tun, was auch immer Sie mit den Dateien machen wollen, die die Frequenzanforderungen erfüllen.

Ich vermute stark, dass es effizientere und phytonischere Wege gibt, dorthin zu gelangen, aber das ist mein bester Gedanke.

Verwandte Themen