2016-06-26 5 views
0

Ich versuche, eine Tab-getrennte Datei zu lesen und alle Zeichen außer Steuerzeichen zu sammeln. Wenn ein Steuerzeichen getroffen wird, sollte der Rest der Zeile ebenfalls ignoriert werden. Ich habe den folgenden Code in Python versucht, 3.5, ein mit for..else loop:Python for..else Schleife löst immer sonst aus

import curses.ascii 

input_file = ... 
chars = set() 
with open(input_file) as file: 
    for line in file.readlines(): 
     source, target = line.split("\t") 

     for c in source.strip() + target.strip(): 
      if curses.ascii.iscntrl(c): 
       print("Control char hit.") 
       break 
      chars.add(c) 
     else: 
      print("Line contains control character:\n" + line) 
      continue 

     print("Line contains no control character:\n" + line.strip()) 

Ich würde erwarten, dass dies jedes Zeichen zu prüfen, für ein Steuerzeichen zu sein, und wenn es einen Treffer (break ausgelöst wird), fahren Sie mit Die nächste Zeile löst somit die else/continue Anweisung aus.

Stattdessen wird continue immer ausgelöst, auch wenn die break-Anweisung in der if-Klausel nie für eine Zeile erreicht wird. Folglich wird die endgültige print-Anweisung auch nie erreicht.

Was mache ich falsch?

+2

die sonst nur ausgelöst, wenn Pause nicht ausgelöst wird. – thebjorn

+2

Hmmm, ich schlage vor, lesen Sie mehr über das 'for ... else' in Python: [Wie kann ich die 'else' Anweisung in Python-Schleifen sinnvoll machen?] (Http://stackoverflow.com/questions/37642573/ how-can-i-make-sense-of-the-else-Anweisung-in-python-loops/37643358 # 37643358) –

+0

Überprüfen Sie dies, wenn es hilft - http://StackOverflow.com/Questions/9979970/Why- does-python-use-else-nach-for-und-while-loops –

Antwort

1

Der else Block einer for Schleife ist nur wenn die for ausgeführt Schleife unterbrochen wurde nie. Sie sehen nur die continue Anweisung im else Block ausgeführt, wenn keine Steuerzeichen in der Zeile waren. Von der for statement documentation:

wenn die Einzelteile aufgebraucht sind (was unmittelbar ist, wenn die Sequenz leer ist oder ein Iterator wirft eine StopIteration Ausnahme), die Suite im else Klausel, falls vorhanden, durchgeführt wird, und die Schleife endet, .

Eine in der ersten Suite ausgeführte Anweisung break beendet die Schleife, ohne die else Klausel-Suite auszuführen.

Ein besserer Test, um zu sehen, ob es Steuerzeichen in einer Linie sind, ist die any() function mit einem generator expression zu verwenden:

if any(curses.ascii.iscntrl(c) for c in source.strip() + target.strip()): 
    print("Line contains control character:\n" + line) 
    continue 

oder Sie können einen regulären Ausdruck verwenden; Diese werden schneller als die Schleife über den Text in C-Code ausgeführt wird, ohne jedes einzelne Zeichen in einer neuen str Objekt Feld mit:

ist
import re 

control_char = re.compile(r'[\x00-\x31]') 

if control_char.search(source.strip() + target.strip()): 
    print("Line contains control character:\n" + line) 
    continue