4. 分支与循环控制语句归纳总结

控制流是编程的骨架。分支和循环,说白了就是让代码能“做选择”和“重复干活”。我做了这么多年批处理脚本,发现很多人把这两块搞混,要么到处用if套if,要么滥用while死循环。这一章咱们把分支和循环彻底捋清楚,再结合MD质控的实际场景,给出一个趁手的兵器谱。

4.1 分支语句:if/elif/else

分支就是给程序装个脑子。if判断条件,满足就走一块,不满足就走另一块。Python的写法很简洁,不用花括号,靠缩进控制块。

qc_pass = True
if qc_pass:
    print("质控通过,继续")
else:
    print("质控失败,标记")

我在项目里见过有人写七八个elif,那个可读性……后来我统一用字典映射或者策略模式代替。建议:elif不超过三层,否则改用数据结构查表。

还有个坑:条件顺序。我曾经把一个宽范围的条件写在前面,结果后面的细粒度分支永远走不到。代码里一定要把最具体、最匹配的判断放最前。

4.2 循环语句:for 与 while

循环就是重复干活。for适合明确迭代次数的场景,while适合条件驱动的场景。下面这张表是我个人的选择习惯:

维度forwhile
适用场景遍历列表、文件行、固定范围状态等待、用户输入重试
代码简洁性高,自带迭代器低,需手动维护计数器
风险不易死循环容易忘记更新条件导致死循环
实战推荐90%的批处理循环仅用于不确定次数的等待

举个例子,批量读取MD文件:

mds = ["sample1.md", "sample2.md", "sample3.md"]
for md in mds:
    process(md)  # 逐文件质控

而while一般用在“直到满足条件”的地方,比如等外部状态文件生成:

import time
while not os.path.exists("qc_done.flag"):
    time.sleep(5)
    print("等待质控完成...")

我个人习惯:能用for绝不写while,少一个计数器就少一个bug。

4.3 循环控制:break、continue、pass

这三个小工具很实用,但也容易用错。说说我的理解:

  • break:立刻跳出整个循环。我在处理质控异常时常用——一旦发现某个样本严重失败,直接终止当前批次后续处理。
  • continue:跳过本次循环剩余语句,进入下一次。适合“跳过不合格样本,继续处理下一个”。
  • pass:啥也不做,占位用。我一般只在写未实现的分支时临时放一个,上线前必须删掉。

警告:break和continue在嵌套循环里只作用于最内层。我曾经忘了这点,在两层for里面用break想跳出外层,结果逻辑全乱了。后来改用函数返回或者异常处理。

for batch in batches:
    for sample in batch:
        if sample.failed_critical:
            break   # 只跳出内层for
    else:
        continue    # 内层没break才执行
    break           # 内层break后跳出外层

嗯,这个“for-else”结构很多新手不知道。其实它特别适合“遍历查找,找到就跳出”的模式。

4.4 实战:质控流程中的控制流

把上面讲的串起来,做一个完整的质控流水线。流程是这样的:

  1. 遍历所有待处理文件(for)
  2. 检查文件格式是否合规(if/else)
  3. 如果格式错误,跳过该文件(continue)
  4. 执行内容校验,失败次数累计(while? 不,这里我用for + 固定重试次数)
  5. 如果致命错误,立即终止整个批次(break + 外层标记)
  6. 否则记录结果,继续下一个

代码示例:

qc_failed = False
for filename in file_list:
    if not is_valid_format(filename):
        print(f"跳过{filename}:格式错误")
        continue
    retry = 3
    for attempt in range(retry):
        result = run_qc(filename)
        if result.passed:
            break
        print(f"第{attempt+1}次尝试失败")
    else:
        qc_failed = True
        break   # 重试全部失败,终止批次
if qc_failed:
    print("批次质控终止")
else:
    print("批次全部通过")

你看,一个for嵌套就解决了重试和终止,没有用while。这种模式我用了好多年,稳定可靠。

4.5 知识图谱:控制流全貌

下面这张图概括了本章所有控制结构的关系。注意:顺序流是隐含的基础,分支和循环在顺序流上搭建,而break/continue是循环内部的“刹车和跳板”。

Python 控制流归纳 顺序执行(默认) 分支 if / elif / else 循环 for / while 循环控制 break(跳出) continue(跳过本次) 使用建议 优先用for,少用while;elif不超过三层;break/continue注意嵌套层级

小技巧:设计控制流时,先画草图(就像上面的SVG),再写代码。我每次设计新的批处理逻辑,都会先在纸上画个流程,能避免很多“else挂错if”的尴尬。

注意:Python的for-else和while-else结构容易让人困惑。记住:else只在循环正常结束(没有被break打断)时执行。调试时可以在else块里加个日志,确认循环是否提前终止。