Python for..else循环总是触发else

时间:2016-06-26 17:36:49

标签: python python-3.x if-statement for-loop

我正在尝试读取制表符分隔文件并收集除控制字符之外的所有字符。如果击中控制字符,则应忽略该行的其余部分。 我使用for..else loop

在Python 3.5中尝试了以下代码
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())

我希望这可以检查每个角色是否为控制角色,如果它击中一个(break被触发),跳到下一行,从而触发else / { {1}}陈述。

相反,即使continue子句中的continue语句从未到达某一行,也会始终触发break。因此,也永远不会达到最终的if语句。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

如果else循环从未中断,for循环的for块仅执行 。如果行中没有控制字符,您只会在continue块中看到else语句。来自for statement documentation

  

当项目耗尽时(当序列为空或迭代器引发StopIteration异常时),将执行else子句中的套件(如果存在),并执行循环终止。

     

在第一个套件中执行的break语句终止循环而不执行else子句的套件。

检查一行中是否有控制字符的更好的测试是any() function使用generator expression

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

或者你可以使用正则表达式;这样做会更快,因为在C代码中完成循环文本而不必在新的str对象中打包每个单独的字符:

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