Python循环控制与函数基础

🎮 break、continue 与函数——让循环听你指挥!

🎯 上集回顾

先来验收一下咱们的学习成果!

上一集我们玩转了 while 循环,不仅用 while 循环搞定了 1 到 100 的求和,还分别用 while 和 for 循环算出了神秘的水仙花数。更酷的是,我们用无限循环 + 循环嵌套给猜数字游戏来了一次大升级!

💭 上集思考题:用 while 循环双重嵌套打印九九乘法表,你做出来了吗?没做出来的话,看完这篇再回去试试,会有新思路哦!


🚦 break 和 continue——循环的"遥控器"

上集我们学了无限循环(也叫死循环),有人说:"死循环一旦跑起来,就再也停不下来了……"

真的只能这样吗? 当然不是!

没学 break 之前,确实有点束手无策——除了强行关掉程序,或者拔电源(开玩笑的😂)。但掌握了 break 之后,就像拿到了循环的"紧急停止按钮",想停就停!另外还有 return 语句也能终止循环,不过它更多用在函数里,后面会讲到。

break 和 continue 就像循环的遥控器,让你能随心所欲地控制循环的执行流程。

🎬 生活小剧场理解概念

🎫 break 的故事——托尼老弟中彩票了!

托尼老弟在美容美发店上班,每天重复着同样的工作,就像个无限循环。突然有一天,他买的彩票中了 5000万!托尼老弟当场把围裙一扔:"老子再也不用上班啦!"

break 就像那张中奖彩票——一旦触发,立刻跳出循环,再也不用回头!

🤧 continue 的故事——托尼老弟感冒了

托尼老弟还在美容美发店上班(毕竟中彩票是小概率事件😅)。今天气温骤降,他感冒了,只能请一天假。但明天病好了,还得继续上班。

continue 就像这场感冒——跳过今天(本次循环),但明天(下一次循环)还得继续!

搞懂了这个比喻,我们来看看代码怎么写!

💥 break 语句——说停就停!

break 的语法超简单,在需要跳出循环的地方写上就行。它通常和 if 语句搭配,满足某个条件时"啪"的一下就跳出去了!

⚠️ 注意:如果在嵌套循环里用 break,它只会跳出当前所在的那一层循环。

while 循环中的 break:

 while 条件表达式1:
     执行代码
     if 条件表达式2:
         break  # 满足条件,立马跑路!

for 循环中的 break:

 for 迭代变量 in 对象:
     if 条件表达式:
         break  # 满足条件,立马跑路!

🎓 实战案例:托尼老弟的逆袭之路

托尼老弟在美发店打工,每天累得像条狗。我跟他说:"坚持学 Python 三个月,你就能脱离苦海!"

来看看托尼老弟是怎么用 break 跳出"打工循环"的:

 study_days = 80  # 已经学了80天
 while True:      # 无限循环——每天重复的生活
     study_days += 1
     print(f'💈 美发店上班,晚上坚持学Python 第 {study_days} 天')
     
     if study_days > 90:  # 学了90天,学成啦!
         print('🎉 Python 已学成,再也不用去美发店上班啦!')
         break  # 跳出循环,解放啦!

💡 代码解读:while True 是个无限循环,代表托尼老弟日复一日的打工生活。当 study_days > 90 时,break 触发,循环结束,托尼老弟成功转型程序员!

⏭️ continue 语句——跳过今天,明天再来!

continue 的语法同样简单。它和 break 的区别在于:break 是彻底退出,continue 只是跳过本次,后面的循环还会继续。

while 循环中的 continue:

 while 条件表达式1:
     执行代码
     if 条件表达式2:
         continue  # 跳过本次循环剩余代码,直接进入下一次

for 循环中的 continue:

 for 迭代变量 in 对象:
     if 条件表达式:
         continue  # 跳过本次循环剩余代码,直接进入下一次

🤒 实战案例:托尼老弟感冒了

托尼老弟学 Python 的第88天,不幸感冒了(可能是熬夜敲代码导致的😂)。今天没法去美发店上班,但明天好了还得继续。

 study_days = 80
 while True:
     study_days += 1
     
     if study_days == 88:  # 第88天感冒了
         print('🤧 老弟今天感冒了,请假一天!')
         continue  # 跳过今天的工作,但循环继续
     
     if study_days > 90:   # 学满90天,成功上岸
         print('🎉 Python 已学成,再也不用去美发店上班啦!')
         break
     
     print(f'💈 美发店上班,晚上坚持学Python 第 {study_days} 天')

💡 代码解读:当 study_days == 88 时,continue 触发,跳过了当天的打印语句,但循环并没有结束。第89天、90天继续执行,直到 break 触发才退出。


🎯 break vs continue 对比总结

语句 作用 形象比喻
break 彻底退出整个循环 辞职不干了,再也不来上班
continue 跳过本次,继续下一次循环 今天请假,明天还得来

⚠️ 重要提醒:在嵌套循环中,break 和 continue 只作用于它们所在的最内层循环!

🧩 函数——代码的"乐高积木"

乐高积木大家都玩过吧?一块块标准化的组件,通过不同的组合方式,能拼出汽车、城堡、飞船……简直无所不能!

函数就是编程世界的"乐高积木"!

随着你写的代码越来越多,程序会越来越复杂,就像一团乱麻。这时候就需要函数来帮忙了——把重复的代码打包起来,要用的时候直接"召唤",代码瞬间变得清爽又优雅!

还记得上一篇猜数字游戏吗?判断用户输入是否合法的代码出现了两次,简直是在复制粘贴。学了函数,这种重复代码就能一键消灭!

🎁 函数有什么用?

优点 说明
🚫 消灭重复 同样的代码不用写N遍,封装成函数,随叫随到
📖 提高可读性 用 calculate_area() 比看一堆公式直观多了
🔧 方便维护 代码有问题?改函数一处,全局生效
🧱 模块化开发 复杂问题拆成小函数,逐个击破

📝 使用函数两步走

 第1步:定义函数(把代码打包)
     ↓
 第2步:调用函数(使用打包好的代码)

Python 自带了很多内置函数,比如 print()、max()、min()、len() 等等,开箱即用。当然,我们也可以自己造轮子——自定义函数!

💪 函数是 Python 编程的基石,一定要跟着文档动手敲,光看是学不会的!

✍️ 定义和调用函数

先来看函数的语法结构:


🎪 开胃菜:pass 语句

在正式写函数之前,先认识一下 pass——它是 Python 里的"占位符",表示"这里暂时空着,我先占个位置"。

比如你想写一个求和函数,但还没想好怎么实现,就可以先用 pass 占位,代码不会报错:

 def 求和(x, y):
     pass  # 先占个坑,以后再来填

💡 pass 就像你占座时放的书包——表示"这个位置有人了",但人还没来。


🎬 实战:热情的打招呼函数

每次上课都想跟大家说10遍"大家好,想死你们了",手动打印太傻了,让函数来帮忙:

def 打招呼():           # 定义函数
    for i in range(10):
        print('大家好,想死你们了!')

打招呼()                # 调用函数

# 🎉 运行结果
大家好,想死你们了!
大家好,想死你们了!
大家好,想死你们了!
大家好,想死你们了!
大家好,想死你们了!
大家好,想死你们了!
大家好,想死你们了!
大家好,想死你们了!
大家好,想死你们了!
大家好,想死你们了!

💡 注意:这个函数没有参数,也没有返回值——函数可以很简单,也可以很复杂,根据需求来!

🎁 参数和返回值——函数的"输入输出"

💝 生动理解:女朋友函数

来听一个有趣的故事,帮你理解参数和返回值:

假设你的女朋友是一个函数:

  • 你给她的关心、买的礼物 → 输入参数(参数)

  • 她的反应、回礼 → 返回值(return)

  • 啥都不给 → 参数为空

  • 她不理你 → 返回 None

函数的灵活性:

  • ✅ 可以没有参数(你不送礼物)

  • ✅ 可以有多个参数(口头关心 + 实物礼物)

  • ✅ 可以没有返回值(她默默收下,没反应)

  • ✅ 可以有返回值(她回赠你一个吻)

当函数执行到 return 时,函数立即结束,后面的代码不会执行!


💔 实战代码:女朋友模拟器

def girlfriend(gift=None):
    """
    女朋友函数
    参数:gift - 你送的礼物
    返回:女朋友的反应
    """
    if gift is None:
        print("😒 啥都不送,还想要我表示?")
        return None  # 没礼物,没好脸色
    
    elif gift == 'LV':
        return "😘 I LOVE YOU!"  # 送LV,收获爱情!
    
    elif gift == '多喝热水':
        print("🙄 滚滚滚!")
        return None  # 直男礼物,凉凉
    
    else:
        print("😐 就这?")
        return "谢谢"  # 普通礼物,礼貌回应

# 测试各种情况
print("=== 测试1:啥都不送 ===")
print(f"结果:{girlfriend()}")

print("\n=== 测试2:送LV ===")
print(f"结果:{girlfriend('LV')}")

print("\n=== 测试3:送'多喝热水' ===")
print(f"结果:{girlfriend('多喝热水')}")

print("\n=== 测试4:送玫瑰花 ===")
print(f"结果:{girlfriend('玫瑰花')}")

🎯 运行结果分析:

输入 输出 说明
无(None) None 没礼物,返回空
'LV' "I LOVE YOU!" 贵重礼物,有返回值
'多喝热水' None 直男礼物,被鄙视
'玫瑰花' "谢谢" 普通礼物,礼貌回应

💡 结论:只有送 LV 的时候,女朋友才给了正面反馈。所以兄弟们,懂了吗?😂

🎭 形参 vs 实参——"剧本"与"演员"

来认识两个重要概念:

概念 英文 比喻 出现位置
形参 形式参数 剧本里的角色 函数定义时
实参 实际参数 实际出演的演员 函数调用时

🎬 实战:计算长方形面积

def rect_area(width, height):      # width、height 是形参(剧本角色)
    area = width * height
    return area

# 调用函数
r_area = rect_area(320, 480)       # 320、480 是实参(实际演员)
print(f"320 × 480 的长方形面积: {r_area}")

# 运行结果
320 × 480 的长方形面积: 153600

💡 记忆口诀:

  • 形参 = 形式上的参数(占位用)

  • 实参 = 实际传的参数(真实数据)

  • 调用时,实参按顺序传给形参——第一个实参给第一个形参,第二个给第二个……

🔑 关键字参数——"点名道姓"传参数

刚才的形参实参是按位置对应的,必须记住哪个参数在前、哪个在后。如果搞混了顺序,结果就错了!

有没有更优雅的方式? 有!关键字参数——直接"点名道姓"告诉函数:这个值是给哪个参数的!


🎯 实战:关键字参数的魅力

def rect_area(width, height):
    area = width * height
    return area

# 方式1:传统位置参数
r_area = rect_area(320, 480)

# 方式2:关键字参数(顺序可以乱!)
r_area = rect_area(width=320, height=480)
r_area = rect_area(height=480, width=320)  # 顺序反过来也行!

print(f"面积: {r_area}")  # 结果都一样:153600

✨ 关键字参数的优势:

优势 说明
📖 可读性强 rect_area(width=320, height=480) 一眼看懂
🔄 顺序自由 不用死记硬背参数顺序
🐛 减少bug 不会因为顺序错误导致奇怪的结果

💡 建议:参数多的函数,优先使用关键字参数,代码更清晰!

🎁 参数默认值——"保底选项"

有时候,某个参数在大多数情况下都是同一个值,只有少数情况会变化。每次都传一样的参数,太麻烦了!

解决方案:给参数设置默认值!


🎯 实战:默认高度为480的长方形

假设你经常计算各种宽度的长方形面积,但高度基本都是480:

def rect_area(width, height=480):  # height有默认值480
    area = width * height
    return area

# 情况1:只传宽度,高度用默认值
r_area = rect_area(320)
print(f"320 × 480 的面积: {r_area}")  # 153600

# 情况2:传两个参数,覆盖默认值
r_area = rect_area(320, 600)
print(f"320 × 600 的面积: {r_area}")  # 192000

# 情况3:用关键字参数,更清楚
r_area = rect_area(width=320)           # 高度用默认480
r_area = rect_area(width=320, height=720)  # 高度改成720


💡 恍然大悟:print() 函数的 end 参数

学了默认参数,终于明白 print() 的 end 参数了!

# print() 的完整形式其实是这样的:
print(value, ..., end='\n')  # end默认是换行符

# 所以默认情况下,每次print都会换行
print("第一行")
print("第二行")

# 如果改成空格,就不会换行了
print("A", end=' ')
print("B", end=' ')
print("C")  # 输出:A B C

🎓 下节预告:关于函数的更多骚操作(可变参数、多返回值),等我们学完元组后再来解锁!

🎮 实战:用函数重构猜数字游戏

学了函数,是时候展示真正的技术了!

还记得上一篇的猜数字游戏吗?那段代码里,判断用户输入是否合法的逻辑出现了两次,简直是复制粘贴的典范:

# 第一次出现
input_string = input("设了个数字,你来猜猜看:")
while not input_string.isdigit():
    input_string = input("您输入了非数字字符,请输入正确的数字:")
else:
    guess_number = int(input_string)

# ... 游戏逻辑 ...

# 第二次出现(一模一样的代码!)
input_string = input("设了个数字,你来猜猜看:")
while not input_string.isdigit():
    input_string = input("您输入了非数字字符,请输入正确的数字:")
else:
    guess_number = int(input_string)

这种重复代码,就是函数的用武之地!


✨ 重构后的优雅代码:

import random

secret_number = random.randint(0, 10)

def get_valid_input():
    """
    获取用户输入的合法数字
    如果输入不是数字,会循环提示直到输入正确
    """
    input_string = input("设了个数字,你来猜猜看:")
    while not input_string.isdigit():
        input_string = input("❌ 输入错误!请输入正确的数字:")
    
    return int(input_string)

# 游戏主逻辑
guess_number = get_valid_input()

while guess_number != secret_number:
    if guess_number > secret_number:
        print("📉 不好意思,您猜大了")
    else:
        print("📈 您猜的有点小")
    
    guess_number = get_valid_input()  # 复用函数!

print("🎉 大吉大利,今晚吃鸡!")

🎯 重构的好处:

优化前 优化后
重复代码写两遍 封装成函数,调用两次
修改要改两处 修改只需改一处
代码冗长难读 逻辑清晰简洁
容易出错 维护成本低

💡 编程格言:DRY - Don't Repeat Yourself(不要重复你自己)!遇到重复代码,第一反应应该是:能不能写成函数?

📚 内置函数——Python 的"百宝箱"

Python 自带了一大波内置函数,开箱即用,无需导入任何模块!

你已经用过很多内置函数了:print()、input()、len()、range()……这些都是 Python 官方给你准备好的"工具",直接拿来用就行。


🧰 Python3 内置函数大全

函数 函数 函数 函数 函数
abs() delattr() hash() memoryview() set()
all() dict() help() min() setattr()
any() dir() hex() next() slice()
ascii() divmod() id() object() sorted()
bin() enumerate() input() oct() staticmethod()
bool() eval() isinstance() open() str()
breakpoint() exec() issubclass() pow() sum()
bytearray() filter() iter() print() super()
bytes() float() len() property() tuple()
callable() format() list() range() type()
chr() frozenset() locals() repr() vars()
classmethod() getattr() map() reversed() zip()
compile() globals() max() round() __import__()
complex() hasattr()

📖 完整文档:Python 官方内置函数文档


🎯 实战:max() 和 min() 函数

这两个函数超级常用,用来找最大/最小值:

# 方式1:直接传多个参数
print(f"max(60, 100, 1000) = {max(60, 100, 1000)}")  # 1000
print(f"min(60, 100, 1000) = {min(60, 100, 1000)}")  # 60

# 方式2:传一个列表/元组
scores = [85, 92, 78, 96, 88]
print(f"最高分: {max(scores)}")  # 96
print(f"最低分: {min(scores)}")  # 78

# 方式3:结合key参数,更强大
words = ["apple", "banana", "cat"]
print(f"最长的单词: {max(words, key=len)}")  # banana

💡 学习建议:不需要死记硬背所有内置函数,遇到需求时去查文档,常用的用多了自然就记住了!

🧊 元组——"冻住"的列表

前面我们学了列表(list),现在来认识它的"表亲"——元组(tuple)!

它们就像一对性格迥异的兄弟:

  • 列表 = 活泼好动,想改就改

  • 元组 = 沉稳内敛,一旦确定就不变

🎭 元组 vs 列表:一对表亲

👬 相同点(家族基因):

特性 说明
📋 都是序列 都有索引、可以切片、可以遍历
📦 都是容器 可以装任意类型的数据
🔢 有序排列 元素按定义顺序存放
🔍 支持 in/not in 可以判断元素是否存在
🔄 可以互转 列表 ↔ 元组 自由转换

⚡ 不同点(性格差异):

特性 列表 [] 元组 ()
可变性 ✅ 随意增删改 ❌ 只读不可改
语法 中括号 小括号
性能 稍慢 更快
安全性 低(容易被改) 高(数据保险)

💡 形象记忆:元组就是"冻住"的列表——tuple 谐音 "特厚"(皮厚冻不坏)😂

✍️ 创建元组的两种方式

方式1:小括号直接创建

# 多个元素
t1 = (1, 2, 3, 4, 5)

# 混合类型
t2 = ("渣男教父", 33, True, "Python")

# 空元组
t3 = ()

方式2:tuple() 函数转换

# 从列表转元组
list_data = [1, 2, 3]
t4 = tuple(list_data)  # (1, 2, 3)

# 从字符串转元组
t5 = tuple("Hello")    # ('H', 'e', 'l', 'l', 'o')

# 从range转元组
t6 = tuple(range(5))   # (0, 1, 2, 3, 4)

⚠️ 超级重点:单元素元组的陷阱!

如果元组只有一个元素,必须加逗号,否则 Python 会认为是普通括号:

# ❌ 错误写法(这不是元组!)
t = (100)
print(type(t))  # <class 'int'>  变成整数了!

# ✅ 正确写法(注意后面的逗号!)
t = (100,)
print(type(t))  # <class 'tuple'>  这才是元组!

# 括号甚至可以省略
t = 100,
print(type(t))  # <class 'tuple'>

💡 记忆口诀:单元素元组,逗号是灵魂!

📦 打包和拆包——元组的"魔法"

元组有一个超级实用的特性——打包(packing)和拆包(unpacking)!

这是 Python 中非常优雅的语法糖,让代码简洁又高效。


📦 打包(Packing)

把多个值"包"进一个元组:

# 等号右边有多个值,自动打包成元组
info = "渣男教父", 33, True, "Game、Python"
print(info)        # ('渣男教父', 33, True, 'Game、Python')
print(type(info))  # <class 'tuple'>

📤 拆包(Unpacking)

把元组里的值"拆"给多个变量:

bafu_info = ('渣男教父', 33, True, 'Game、Python')

# 拆包:左边变量数 = 右边元素数
name, age, married, hobby = bafu_info

print(f"姓名: {name}")      # 渣男教父
print(f"年龄: {age}")       # 33
print(f"已婚: {married}")   # True
print(f"爱好: {hobby}")     # Game、Python

🎯 完整演示:

# 1️⃣ 先打包
bafu_info = ('渣男教父', 33, True, 'Game、Python')
print(f"📦 打包结果: {bafu_info}")

# 2️⃣ 再拆包
name, age, married, hobby = bafu_info
print(f"📤 拆包结果: {name}, {age}, {married}, {hobby}")

# 3️⃣ 重新打包(顺序打乱)
info = name, hobby, age, married
print(f"📦 再打包: {info}")

# 输出:
# 📦 打包结果: ('渣男教父', 33, True, 'Game、Python')
# 📤 拆包结果: 渣男教父, 33, True, Game、Python
# 📦 再打包: ('渣男教父', 'Game、Python', 33, True)

💡 核心规则:拆包时,左边变量的数量必须等于右边元素的数量,否则会报错!

🌟 函数可变参数——想传几个传几个!

还记得前面说的元组打包拆包吗?现在它要跟函数联手搞事情了!

场景:你想写一个函数,计算任意个数的数字之和。但问题是——不知道用户会传几个数!

解决方案:*args 可变参数!


🔮 魔法语法:*args

在定义函数时,给参数前面加个 *,它就变成了"可变参数":

def my_sum(*numbers):  # * 表示接收任意数量的参数
    """计算任意个数数字的和"""
    total = 0
    for n in numbers:
        total += n
    return total

# 调用时可以传任意个数!
print(my_sum(1, 2, 3))      # 6
print(my_sum(10, 20))       # 30
print(my_sum())             # 0
print(my_sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))  # 55

💡 原理揭秘:*numbers 会把传入的所有参数打包成一个元组!


🎁 函数的"多返回值"

Python 函数可以一次返回多个值,本质上就是返回一个元组:

def calculate(a, b):
    """同时返回和、差、积、商"""
    sum_val = a + b
    diff_val = a - b
    prod_val = a * b
    quot_val = a / b if b != 0 else None
    
    return sum_val, diff_val, prod_val, quot_val  # 返回4个值!

# 拆包接收多个返回值
s, d, p, q = calculate(10, 3)
print(f"和: {s}, 差: {d}, 积: {p}, 商: {q:.2f}")
# 输出:和: 13, 差: 7, 积: 30, 商: 3.33


🎯 综合实战:奇偶分离器

def separate_odd_even(*numbers):
    """
    接收任意数量的整数
    返回:奇数之和, 偶数之和
    """
    odd_sum = 0    # 奇数和
    even_sum = 0   # 偶数和
    
    for num in numbers:
        if num % 2 == 0:
            even_sum += num
        else:
            odd_sum += num
    
    return odd_sum, even_sum  # 返回两个值!

# 调用
odd, even = separate_odd_even(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print(f"奇数之和: {odd}")    # 25
print(f"偶数之和: {even}")   # 30

🎓 下节预告:今天只是函数的入门,后续还会讲函数嵌套、变量作用域、匿名函数(lambda)等高级玩法,敬请期待!

文档总结

一、核心知识点回顾

1. 循环控制语句

语句 作用 使用场景
break 立即终止当前循环,跳出循环体 当满足某个条件时需要提前结束循环,如找到目标值后停止搜索
continue 跳过本次循环的剩余代码,直接进入下一次循环 当满足某个条件时需要跳过当前迭代,如过滤掉某些不符合条件的数据

重要提醒:在嵌套循环中,break 和 continue 只作用于它们所在的最内层循环。

2. 函数基础

函数的定义与调用流程:

定义函数(def) → 封装代码块 → 调用函数(函数名()) → 执行代码

函数的组成部分:

  • 函数名:标识函数的名称,遵循命名规范

  • 参数:函数的输入,分为形参(定义时)和实参(调用时)

  • 函数体:实现具体功能的代码块

  • 返回值:函数的输出,使用 return 语句返回

参数传递方式:

  1. 位置参数:按顺序传递,实参与形参一一对应

  2. 关键字参数:通过 参数名=值 的方式传递,可以打乱顺序

  3. 默认参数:在定义时给参数指定默认值,调用时可省略

  4. 可变参数:使用 *args 接收任意数量的位置参数,自动打包成元组

3. 元组(tuple)

元组与列表的对比:

特性 列表(list) 元组(tuple)
语法 [元素1, 元素2] (元素1, 元素2)
可变性 可变 - 可以增删改元素 不可变 - 只能读取,不能修改
性能 相对较慢 相对较快
使用场景 需要频繁修改的数据集合 固定不变的数据集合、函数多返回值

打包与拆包:

  • 打包:将多个值赋给一个变量时,自动组合成元组

  • 拆包:将元组中的元素分别赋值给多个变量

  • 应用:函数的多返回值本质就是元组打包,接收时可以用拆包语法

4. 内置函数

Python 提供了丰富的内置函数,本文档重点介绍了 max() 和 min(),它们可以:

  • 接收多个独立参数:max(1, 5, 3) → 返回 5

  • 接收一个可迭代对象:max([1, 5, 3]) → 返回 5

二、学习建议

  1. 函数是代码复用的核心:遇到重复代码时,第一时间考虑是否可以封装成函数

  2. 参数设计要灵活:合理使用默认参数和可变参数,让函数更通用

  3. 理解不可变性的意义:元组的不可变性使其成为字典的键、集合的元素,也保证了数据安全

  4. 多练习打包拆包:这是 Python 中非常优雅的特性,熟练掌握可以让代码更简洁

三、下篇预告

下一篇我们将学习 Python 中另外两种重要的数据结构——字典(dict)和集合(set),以及面向对象编程的基础——类与对象。字典是键值对的集合,非常适合表示有映射关系的数据;集合则用于存储不重复的元素,常用于去重和集合运算。


🎮 动手练一练

光看不练假把式!下面几道题目帮你巩固今天学到的知识,建议先自己思考,再看参考答案。

选择题

1. 以下关于 break 语句的描述,正确的是?

  • A. 用于跳出当前循环

  • B. 用于跳过当前循环的剩余语句

  • C. 用于结束整个程序

  • D. 用于定义函数

​

💡 答案解析(点击展开)

​

正确答案:A

详细解析:

  • break 语句的作用是立即终止它所在的那一层循环,程序会跳出循环体,继续执行循环后面的代码。

  • 选项 B 描述的是 continue 的功能,continue 是跳过本次循环剩余代码,继续下一次循环。

  • 选项 C 错误,结束整个程序应该使用 exit() 或 quit()(不推荐在生产环境使用)。

  • 选项 D 错误,定义函数使用 def 关键字。

记忆技巧:break 有"打破、中断"的意思,想象你正在循环里跑步,break 就是突然喊停,直接退出跑道。


2. 以下关于 continue 语句的描述,正确的是?

  • A. 用于跳出当前循环

  • B. 用于跳过当前循环的剩余语句,继续下一次循环

  • C. 用于结束整个程序

  • D. 用于定义函数

​

💡 答案解析(点击展开)

​

正确答案:B

详细解析:

  • continue 语句的作用是跳过当前迭代中循环体剩余的代码,直接进入下一次循环的判断。

  • 与 break 的区别:break 是彻底结束循环,continue 只是跳过当前这一轮,后面还会继续循环。

生活类比:

  • 假设你每天要去健身房锻炼(循环),break 相当于你决定以后再也不去了(彻底退出)。

  • continue 相当于今天太累了,跳过今天的训练,但明天还会去(只跳过这一次)。

代码示例加深理解:

for i in range(5):
    if i == 2:
        continue  # 跳过 i=2 的打印
    print(i)
# 输出:0 1 3 4(注意没有 2)

3. 以下关于函数的描述,错误的是?

  • A. 函数可以减少代码重复

  • B. 函数可以提高代码可读性

  • C. 函数必须有返回值

  • D. 函数可以有多个参数

​

💡 答案解析(点击展开)

​

正确答案:C

详细解析:

  • 选项 A 正确:将重复代码封装成函数,需要时直接调用,避免复制粘贴。

  • 选项 B 正确:用有意义的函数名将一段逻辑封装起来,代码更易读。比如 calculate_area() 比一堆计算公式直观。

  • 选项 C 错误:函数可以没有返回值!没有 return 语句的函数,或者只有 return 没有返回值的函数,默认返回 None。

    def say_hello():
        print("Hello!")
        # 没有 return 语句
    
    result = say_hello()  # 输出:Hello!
    print(result)         # 输出:None
    
  • 选项 D 正确:Python 函数支持任意数量的参数,包括位置参数、关键字参数、可变参数等。

常见误区:很多初学者认为函数一定要有 return,其实像 print() 这种执行操作但不需要返回结果的函数也很常见。


编程题

1. 编写一个函数,判断一个数是否为素数(质数)。

💡 提示:素数是指大于1的自然数,除了1和它本身外,不能被其他自然数整除。

​

🔑 参考答案与解析(点击展开)

​

解题思路:

  1. 边界处理:小于2的数都不是素数

  2. 优化算法:不需要从2检查到n-1,只需要检查到 √n 即可。因为如果 n 有因子大于 √n,那它必然对应一个小于 √n 的因子。

  3. 遍历检查:用循环检查2到√n之间是否存在能整除n的数

代码实现:

def is_prime(n):
    """判断是否为素数
    
    参数:
        n: 待判断的整数
    返回:
        bool: True表示是素数,False表示不是素数
    """
    # 边界条件:小于2的数不是素数
    if n < 2:
        return False
    
    # 2是素数,但偶数都不是素数(除了2)
    if n == 2:
        return True
    if n % 2 == 0:
        return False
    
    # 只需要检查到平方根,且跳过偶数
    for i in range(3, int(n**0.5) + 1, 2):
        if n % i == 0:
            return False
    
    return True

# 测试用例
print(is_prime(17))   # True,17是素数
print(is_prime(18))   # False,18 = 2 × 9
print(is_prime(2))    # True,2是最小的素数
print(is_prime(1))    # False,1不是素数
print(is_prime(97))   # True,97是素数

进一步优化:上面的代码已经做了优化(跳过偶数),如果n很大,这个算法效率会高很多。

时间复杂度:O(√n),比朴素的 O(n) 算法高效得多。


2. 编写一个函数,计算斐波那契数列的前n项。

💡 提示:斐波那契数列是 0, 1, 1, 2, 3, 5, 8, 13...,从第三项开始,每一项都是前两项之和。

​

🔑 参考答案与解析(点击展开)

​

解题思路:

  1. 理解数列规律:F(0)=0, F(1)=1, F(n)=F(n-1)+F(n-2)

  2. 处理边界情况:n<=0 返回空列表,n==1 返回 [0]

  3. 迭代计算:从第3项开始,每一项等于前两项之和

代码实现:

def fibonacci(n):
    """返回斐波那契数列前n项
    
    参数:
        n: 要计算的项数
    返回:
        list: 包含前n项斐波那契数的列表
    """
    # 处理边界情况
    if n <= 0:
        return []
    elif n == 1:
        return [0]
    elif n == 2:
        return [0, 1]
    
    # 初始化前两项
    fib = [0, 1]
    
    # 从第3项开始计算,每一项等于前两项之和
    for i in range(2, n):
        next_num = fib[i-1] + fib[i-2]
        fib.append(next_num)
    
    return fib

# 测试用例
print(fibonacci(0))   # []
print(fibonacci(1))   # [0]
print(fibonacci(2))   # [0, 1]
print(fibonacci(10))  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
print(fibonacci(20))  # 前20项

# 进阶:只返回第n项(不保存整个列表)
def fibonacci_nth(n):
    """只返回第n项斐波那契数,空间复杂度 O(1)"""
    if n <= 0:
        return None
    elif n == 1:
        return 0
    elif n == 2:
        return 1
    
    a, b = 0, 1
    for _ in range(2, n):
        a, b = b, a + b  # 同时赋值,Pythonic的写法
    return b

print(f"第20项是: {fibonacci_nth(20)}")  # 4181

知识点延伸:

  • 上面的 a, b = b, a + b 是 Python 特有的同步赋值,先计算右边所有值,再赋给左边。

  • 如果只关心第n项的值,可以用优化版本,只保存前两个数,空间复杂度从 O(n) 降到 O(1)。


3. 编写一个函数,接收任意数量的整数,返回其中的最大值和最小值。

💡 提示:需要使用可变参数 *args,并且函数要有两个返回值。

​

🔑 参考答案与解析(点击展开)

​

解题思路:

  1. 使用可变参数 *args:这样函数可以接受任意数量的参数,如 find_max_min(1, 5, 3) 或 find_max_min()

  2. 处理空参数情况:如果没有传入任何参数,应该返回什么?这里返回 (None, None)

  3. 利用内置函数:Python 已经提供了 max() 和 min(),直接复用即可

  4. 多返回值:Python 函数返回多个值时,实际上是返回一个元组,可以用拆包语法接收

代码实现:

def find_max_min(*numbers):
    """接收任意数量的整数,返回最大值和最小值
    
    参数:
        *numbers: 可变数量的整数参数
    返回:
        tuple: (最大值, 最小值),如果没有参数返回 (None, None)
    """
    # 检查是否有参数传入
    if not numbers:
        print("警告:没有传入任何参数!")
        return None, None
    
    # 使用内置函数计算最大最小值
    return max(numbers), min(numbers)

# 测试用例
# 1. 正常情况
max_val, min_val = find_max_min(3, 1, 4, 1, 5, 9, 2, 6)
print(f"最大值: {max_val}, 最小值: {min_val}")  # 最大值: 9, 最小值: 1

# 2. 只有一个数
max_val, min_val = find_max_min(42)
print(f"最大值: {max_val}, 最小值: {min_val}")  # 最大值: 42, 最小值: 42

# 3. 没有参数
max_val, min_val = find_max_min()
print(f"最大值: {max_val}, 最小值: {min_val}")  # 最大值: None, 最小值: None

# 4. 传入列表(需要解包)
data = [23, 56, 12, 89, 34]
max_val, min_val = find_max_min(*data)  # 注意这里的 * 是解包操作
print(f"列表中的最大值: {max_val}, 最小值: {min_val}")  # 最大值: 89, 最小值: 12

重要知识点:

  1. *numbers 在定义函数时:表示接收任意数量的位置参数,内部是一个元组

  2. *data 在调用函数时:表示解包,将列表/元组的元素逐个作为参数传入

手动实现版本(不使用内置函数):

def find_max_min_manual(*numbers):
    """手动实现最大最小值查找"""
    if not numbers:
        return None, None
    
    max_val = min_val = numbers[0]  # 初始化为第一个数
    
    for num in numbers[1:]:
        if num > max_val:
            max_val = num
        if num < min_val:
            min_val = num
    
    return max_val, min_val

4. 使用 break 和 continue 实现:打印1-100之间能被3整除但不能被5整除的数。

💡 提示:需要同时满足两个条件:能被3整除,且不能被5整除。

​

🔑 参考答案与解析(点击展开)

​

解题思路:

  1. 遍历范围:使用 range(1, 101) 生成1到100的数字

  2. 第一个条件:num % 3 != 0 表示不能被3整除,用 continue 跳过

  3. 第二个条件:num % 5 == 0 表示能被5整除,也用 continue 跳过

  4. 输出结果:通过两个条件的数,打印出来

代码实现:

print("1-100之间能被3整除但不能被5整除的数:")

count = 0  # 计数器,统计有多少个符合条件的数
for num in range(1, 101):
    # 条件1:不能被3整除,跳过
    if num % 3 != 0:
        continue
    
    # 条件2:能被5整除,跳过(因为要求"不能被5整除")
    if num % 5 == 0:
        continue
    
    # 通过筛选,打印该数
    print(num, end=' ')
    count += 1
    
    # 每行打印10个数,方便阅读
    if count % 10 == 0:
        print()  # 换行

print(f"\n\n符合条件的数共有 {count} 个")

# 输出结果:
# 3 6 9 12 18 21 24 27 33 36 
# 39 42 48 51 54 57 63 66 69 72 
# 78 81 84 87 93 96 99 
# 
# 符合条件的数共有 27 个

另一种写法(使用逻辑与):

print("\n使用逻辑与的写法:")
for num in range(1, 101):
    # 同时满足:能被3整除 且 不能被5整除
    if num % 3 == 0 and num % 5 != 0:
        print(num, end=' ')

两种写法对比:

写法 特点 适用场景
continue 写法 条件分散,逻辑清晰,适合多条件复杂筛选 条件很多,需要分别处理
and 写法 条件集中,代码简洁 条件简单,一目了然

数学原理:

  • 能被3整除的数:3, 6, 9, 12, 15, 18, 21, 24, 27, 30...

  • 其中能被5整除的(即能被15整除的):15, 30, 45, 60, 75, 90

  • 所以符合条件的数有:100÷3 ≈ 33个,减去6个能被15整除的,约27个

posted @ 2026-07-23 20:23  渣男教父  阅读(24)  评论(0)    收藏  举报