Python for..else 循环总是触发 else
Posted
技术标签:
【中文标题】Python for..else 循环总是触发 else【英文标题】:Python for..else loop always triggers else 【发布时间】:2016-10-28 17:15:56 【问题描述】:我正在尝试读取一个制表符分隔的文件并收集除控制字符之外的所有字符。如果命中控制字符,则该行的其余部分也应被忽略。
我在 Python 3.5 中尝试了以下代码,使用 for..else
loop:
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
/continue
语句。
反而会发生continue
总是被触发,即使if
子句中的break
语句从未到达一行。因此,最终的print
语句也永远不会到达。
我做错了什么?
【问题讨论】:
只有在没有触发break时才会触发else。 嗯,我建议你阅读更多关于python中for...else
的信息:How can I make sense of the else
statement in Python loops?
看看这个是否有帮助 - ***.com/questions/9979970/…
感谢大家,您的提示对您有所帮助。不过,我觉得这个术语有些混乱。
如果您尝试将 else
与 for 配对,可能会造成混淆。我不认为关键字 else 是这种语法的好选择,但如果你将 else 与 break 配对,你会发现它实际上是有意义的。让我展示一下它在人类语言中是如何工作的。 --for
一组嫌疑人中的每个人if
任何人都是罪犯break
调查。 else
报告失败。
【参考方案1】:
for
循环的else
块仅在for
循环从未被中断的情况下执行。如果行中没有控制字符,您只会看到在else
块中执行的continue
语句。来自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
【讨论】:
以上是关于Python for..else 循环总是触发 else的主要内容,如果未能解决你的问题,请参考以下文章
C++ 中是不是有与“for ... else”Python 循环等效的方法?