摘要部分指出, 循环这一知识点是每一个编程初学者都必须跨越的一道重要关卡。这篇文章将通过展示十个以上的具体实例, 对 for 循环、while 循环以及 break 语句的使用方法及其相互之间的区别进行系统性的讲解, 旨在帮助读者从根本上消除对死循环现象的困扰, 并避免因逻辑不清晰而带来的混乱情况。
程序能够从一次性使用的工具, 进化为自动化引擎的一个关键分水岭, 就是循环的存在。如果没有掌握循环这一技巧, 你所面对和操作的, 仅仅是相互独立、孤立存在的一条数据记录而已。
相反地, 当你学会了去运用循环之后, 原本繁杂的数据表格、庞大的文件内容、或者是通过 API 接口所获取到的所有返回结果等等种种情形之中的全部信息, 都能够完全地处在你的个人掌控范围之内了。
然而非常有趣的是, 在实际编程的过程中, 绝大多数刚入行的新手们往往会在这一点上陷入僵局或者遇到难以逾越的障碍问题, 具体表现为他们不太明白究竟在什么样的时间场景之下适合使用 for 循环结构? 又或者说在何种特定条件下才应该采用 while 循环结构来进行执行动作?
更进一步地说, break 语句功能与 语句功能之间各自的具体含义指向以及实际操作用法方面到底是存在着怎样一种明确的界定关系? 这篇文章的目标就是一个: 让你读完以后, 彻底不用再去心里反复掂量、琢磨那些令人犯难的事儿。
for循环, 就是在你心里十分清楚自己究竟需要去挨个儿走过一遍那些具体内容的时候, 你应当去选择它。
for 循环的核心意思就是, 对某一个列表里面的每一个项目、字符串里面的每一部分字符、字典里面的每一种情况、文件里面的某一项对象进行操作。只要你的手上存在着一个可以进行连续处理的对象, 那么选择 for 这个形式就是最直接的方法。
# 遍历列表fruits = ["苹果", "香蕉", "橘子"]
for fruit in fruits:
print(f"今天吃{fruit}")
与C系语言相比, 其for循环的工作机制并不依赖于通过索引增加数字的方式来使进程向前推进, 而是基于迭代器协议来运作。这就导致了这样一个结果, 即在绝大多数情况下, 使用者能够直接对不同类型的集合对象开展实际操作。
# 遍历字典的键和值scores = {"小明": 92, "小红": 85, "小刚": 78}
for name, score in scores.items():
print(f"{name} 考了 {score} 分")
# 遍历字符串
for char in "Python":
print(char)
当需要数值范围的时候, range() 这一个函数就是特别好用的一个搭档。
# range(start, stop, step)for i in range(1, 10, 2): # 1, 3, 5, 7, 9
print(i)
一个常见的坑:边遍历边修改
不少初学者在刚开始的时候, 经常会去编写那种样式的代码。
# 错误示范nums = [1, 2, 3, 4, 5]
for n in nums:
if n % 2 == 0:
nums.remove(n) # 灾难——迭代器被打乱了
当你正在遍历一个集合, 并且在同一个时候去修改这个原始的集合, 那么这样做会导致程序跳过某些元素发生错误, 或者导致索引超出合法范围。所以, 正确的解决办法就是另外创建一个新的空列表。
nums = [1, 2, 3, 4, 5]nums = [n for n in nums if n % 2 != 0]
while 循环:当你不知道要跑多少轮
while, 这一概念所针对的是另一种类型的问题。在我们进入循环体之前并不需要考虑执行的次数究竟是多少, 我们真正在意的是某个特定的条件会在什么时候发生转变并且变为假这一事实。
# 经典场景:用户输入password = ""
while password != "123456":
password = input("请输入密码:")
print("登录成功")
像这种场合, 去用那个叫for的循环是根本写不来的, 原因是你压根就不清楚对方会往错误里面扎几次。
另外一种很常见的应用场景, 是针对那些长度有上限, 不过具体到底多长谁也说不准的数据流转进行处理。
# 读取文件直到末尾with open("data.txt") as f:
line = f.readline()
while line:
print(line.strip())
line = f.readline()
while 语句里面有一个非常危险的陷阱, 这就是容易形成死循环的情况。
在每一个由 while 关键字定义的循环体内部, 都必须存在至少一种操作, 这种操作正在以一种不可逆转的方式让循环变量或者相关状态逐步靠近那个用来停止循环的设定目标,一旦疏忽而忘记了去执行这样的更新步骤, 那么整个程序就会陷入到没有尽头的无限运行状态之中去。
# 危险——永远不会停count = 0
while count < 10:
print(count)
# 漏掉了 count += 1
这是一个防御性的习惯: 每次编写 while 循环的时候, 先在循环体的末尾位置写下推动条件发生变化的语句, 紧接着再去写上面的其他逻辑。
break:紧急出口
break 的作用是非常简单和直接的, 它的主要功能是立即终止整个循环的执行过程, 然后直接跳转到位于该循环之后的第一条语句继续执行。
可以把 break 想象成一条应急用的消防通道, 在正常情况下人们是绝对不会走这条通道的, 然而一旦触发了特定的条件或者情况发生了变化, 那么就会立马使用这条通道, 导致当前的流程或游戏状态立即结束并切换到下一个指定的环节。
最普遍使用的这种办法, 是在while True这个没有尽头的循环步骤里头, 去设定一个可以退出来的出口。
while True:cmd = input("输入命令(q 退出):")
if cmd == "q":
break
print(f"执行:{cmd}")
在for循环里面使用break这个方法, 经典的应用场景其实就是这样的, 也就是找到了特定的目标之后就不再继续努力了, 直接结束当前的循环过程就可以了。
# 在列表中查找第一个偶数nums = [1, 3, 7, 8, 9, 10]
for n in nums:
if n % 2 == 0:
print(f"第一个偶数是 {n}")
break
# 输出:第一个偶数是 8(9 和 10 不会再看)
break这个动作, 还能够和那种叫做for...else的结构结合在一起, 从而达成一种目的, 这种目的就是去判断是否已经把所有地方都搜了个遍, 结果是根本没有找到任何东西。
for n in nums:if n > 100:
print("找到了超大数")
break
else:
print("没有超过 100 的数")
在这段代码里, else 语句仅仅是在循环完整执行完毕、没有中途被 break 关键词强行中断的时候才会被执行。这种写法其实是一个模式, 虽然很多人对这个模式很容易产生误解, 但它确实是非常实用的一个技巧。
当前操作选择为跳过这一轮。
我们可以这样去理解这个问题, break 就像是整栋大楼里那种响起的消防警铃, 而那一个特定的代码标记则像是某一楼层里面的自动门功能, 具体来说它仅仅只是跳过当前所在的那一轮具体的迭代过程, 接着这个循环就会继续地执行下一轮的相应操作。
# 只打印奇数for i in range(10):
if i % 2 == 0:
continue # 偶数直接跳过,不执行 print
print(i)
# 输出:1, 3, 5, 7, 9
在进行数据的清洗工作时候, 这个功能是特别好用的。
# 过滤脏数据raw_data = ["42", " ", "hello", "99", ""]
for item in raw_data:
item = item.strip()
if not item: # 空字符串跳过
continue
if not item.isdigit(): # 非数字跳过
continue
print(int(item))
# 输出:42, 99
有一个好处, 这个好处并不是非常明显, 可能大家容易忽略, 那就是它能够减少那些需要一层又一叠嵌套起来的层级结构。大家来看一下对比的例子:
# 深嵌套——阅读体验差for item in data:
if item:
if item.is_valid():
if item.score > 60:
process(item)
# 用 continue 拉平——清爽很多
for item in data:
if not item:
continue
if not item.is_valid():
continue
if item.score <= 60:
continue
process(item)
关于四种工具, 其实有着一套可供参考的选取原则和技巧。
不用刻意去背诵。当你写得足够多之后, 这些知识点自然而然就会内化到你的知识体系之中。然而, 在你第一次进行写作的过程中, 你应该把它当作一个检查清单来使用。
例如, 如果你问自己是否在用一个集合, 那么答案就是 for 循环。同样地, 如果你在等待某个条件变为 False, 那么你的选择就应该是 while 循环。
循环, 它并不是一种所谓的语法规则, 而是一种需要长期积累下来的思维习惯。
当你在面对实际问题的过程中, 能够不经过刻意思考, 直接将那些描述性的语言, 比如针对表中的每一个行项目去执行某项操作这件事, 或者是一直提出问题然后等待对方给出符合要求的正确答案这一过程, 又或者是发现数据不符合规范就跳过处理同时确保整体的扫描流程不会被中断这类逻辑, 很自然地转变成对应的代码实现的时候, 你就已经跨越了一个门槛。
在这个时候, 循环这个概念, 就不再是一个需要你费力去攻克的难点知识点了, 相反, 它会变得非常顺手, 就像是你工具箱里面那把使用频率最高、也最顺手的一把钳子一样, 随时可以用上。
假如你个人觉得该篇内容具备实际价值, 你可以选择执行收藏操作以将其保存至个人中心, 以便在下一次编写用于循环结构的程序代码过程中遭遇思维阻塞且推进困难之时, 随时调取并查阅该表格中的相关参考信息。同时我们诚挚地邀请你向身边所有正处于系统学习编程知识阶段的同伴人士进行转发与分享。