Python基础语法练习题参考答案:变量、循环与条件判断
本篇教程提供Python基础语法中变量赋值、类型转换、多分支条件判断、for与while循环控制的典型练习题及详细参考答案。通过代码示例、执行图解与避坑指南,帮助读者切实掌握Python核心编程逻辑。
一、变量赋值与数据类型转换练习题
变量是程序在内存中保存状态的命名标识符。在 Python 中,变量无须显式声明类型,解释器会根据赋给变量的对象动态确定其类型。然而,动态类型并不意味着可以任意混用类型进行算术运算,从外部输入(如 input())获取的数据默认为字符串(str),在参与计算前必须进行显式类型转换。
练习题 1:摄氏度与华氏度双向转换器
题目要求:编写一段程序,将给定的摄氏温度转换为华氏温度,并计算华氏温度对应的反向结果,输出结果保留 2 位小数。转换公式为:F = C * 1.8 + 32,反向公式为:C = (F - 32) / 1.8。要求验证对纯数字字符串的类型转换过程。
解题分析:
- 接收输入的温度数据通常为字符串格式,直接与数值进行乘加运算会触发
TypeError,必须先使用float()函数将其转换为浮点数。 - 浮点数运算可能产生微小的精度偏差,在最终呈现结果时推荐使用 Python 格式化字符串(f-string)语法
{val:.2f}控制显示精度。
# 练习题 1 参考代码:摄氏度与华氏度转换
def temperature_converter(raw_celsius_input: str) -> None:
# 1. 显式类型转换:从 str 转换为 float
celsius = float(raw_celsius_input)
# 2. 算术运算计算华氏度
fahrenheit = celsius * 1.8 + 32.0
# 3. 逆向推导摄氏度,检验对称性
celsius_reconstructed = (fahrenheit - 32.0) / 1.8
# 4. 格式化输出运行结果
print(f"原始摄氏温度: {celsius:.2f} ℃")
print(f"转换华氏温度: {fahrenheit:.2f} ℉")
print(f"逆向校验温度: {celsius_reconstructed:.2f} ℃")
# 执行函数调用
temperature_converter("25.5")
转换华氏温度: 77.90 ℉
逆向校验温度: 25.50 ℃
练习题 2:购物小票总价与累加器模式
题目要求:给定一组商品单价字符串序列 ["19.9", "45.0", "12.8", "5.5"],使用一个累加器变量 total 计算所有商品的总金额。如果总价超过 50 元,享受 9 折优惠,最终输出实付金额与节省金额。
# 练习题 2 参考代码:累加器模式与折扣计算
price_strings = ["19.9", "45.0", "12.8", "5.5"]
# 初始化累加器变量
total_amount = 0.0
# 遍历并累加单价
for price_str in price_strings:
price = float(price_str)
total_amount += price
# 折扣规则判断
if total_amount > 50.0:
discount_rate = 0.9
final_pay = total_amount * discount_rate
saved_money = total_amount - final_pay
else:
final_pay = total_amount
saved_money = 0.0
print(f"商品原始总额: {total_amount:.2f} 元")
print(f"折后实付金额: {final_pay:.2f} 元 (节省: {saved_money:.2f} 元)")
折后实付金额: 74.88 元 (节省: 8.32 元)
在 Python 中,所有数据(无论是整数、浮点数还是字符串)都是以“对象”的形式保存在堆内存中的。变量名 total_amount 本质上是指向该对象的内存引用地址。当执行 total_amount += price 时,因为数值对象在 Python 中是不可变类型(Immutable),解释器并没有就地修改原对象,而是计算出新的数值对象,并将 total_amount 重新绑定到新对象的地址上。
二、条件分支与逻辑判断练习题
条件判断通过 if、elif 和 else 关键字构建程序的决策流转。Python 根据布尔表达式的值(True 或 False)决定执行哪一个代码块。多分支判断遵循“从上到下、互斥短路”的特性:一旦上方某一个分支条件计算为 True,执行完该分支代码后,整个 if-elif-else 结构立即终止,不再评估后续任何 elif 或 else。
练习题 3:学生成绩综合分级与异常校验
题目要求:输入一个成绩百分制数值(0~100):
- 如果数值小于 0 或大于 100,判定为“输入异常”;
- 90 分及以上评定为“优秀”;
- 80 分至 89 分评定为“良好”;
- 60 分至 79 分评定为“及格”;
- 60 分以下评定为“不及格”。
解题分析:
- 优先排查异常值(边界外的值),可以采用逻辑运算符
or:score < 0 or score > 100。 - 在后续的合法区间判断中,因为进入
elif score >= 80的前提已经是score < 90(前一个分支未命中),所以不需要重复书写score >= 80 and score < 90。这种利用短路互斥特性的写法更加简洁高效。
# 练习题 3 参考代码:分级判定与防御性编程
def evaluate_grade(score: float) -> str:
# 1. 异常前置过滤(防御性检查)
if score < 0 or score > 100:
return "输入错误:成绩必须在 0 到 100 之间"
# 2. 依次匹配评分阶梯(依赖互斥短路)
if score >= 90:
return "优秀"
elif score >= 80:
return "良好"
elif score >= 60:
return "及格"
else:
return "不及格"
# 验证各类临界输入
test_scores = [105, 90, 89.5, 75, 60, 59, -5]
for s in test_scores:
print(f"分数: {s:>5} -> 评级: {evaluate_grade(s)}")
分数: 90 -> 评级: 优秀
分数: 89.5 -> 评级: 良好
分数: 75 -> 评级: 及格
分数: 60 -> 评级: 及格
分数: 59 -> 评级: 不及格
分数: -5 -> 评级: 输入错误:成绩必须在 0 到 100 之间
练习题 4:复合逻辑判断——闰年判定器
题目要求:公历纪年法中判定闰年的规则为:年份能被 4 整除但不能被 100 整除,或者能被 400 整除。编写函数 is_leap_year(year: int) -> bool,使用一行简洁的复合逻辑表达式返回布尔值,并输出该年 2 月份的实际天数。
# 练习题 4 参考代码:复合逻辑与运算符优先级
def is_leap_year(year: int) -> bool:
# 根据优先级:and 优先级高于 or,但加括号能够明确表达意图
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
def get_february_days(year: int) -> int:
if is_leap_year(year):
return 29
else:
return 28
# 典型年份测试
years = [2000, 1900, 2024, 2025]
for y in years:
status = "闰年" if is_leap_year(y) else "平年"
print(f"{y} 年是{status},2月份共有 {get_february_days(y)} 天")
1900 年是平年,2月份共有 28 天
2024 年是闰年,2月份共有 29 天
2025 年是平年,2月份共有 28 天
初学者容易犯的一个严重逻辑错误是将更宽松的条件放在严苛条件之前。例如:若先写 if score >= 60: return "及格",后续再写 elif score >= 90: return "优秀",则所有 90 分以上的成绩都会在第一个条件提前命中并返回“及格”,导致第二个分支永远无法被执行。在编写 if-elif 结构时,必须遵循由窄到宽、从严格到包容的顺序排列。
三、循环结构与流程控制练习题
循环是执行重复性操作的核心工具。Python 提供了两种基本循环结构:
for循环:通常配合range()或可迭代对象使用,用于已知遍历次数或已知数据集合的场景;while循环:依赖一个布尔条件,用于循环次数未知、直到满足某种收敛状态的场景。
break 语句用于彻底跳出整个循环,而 continue 语句则用于跳过本次循环剩余代码,直接开始下一次迭代。
练习题 5:筛选指定区间内的素数(双重 for 循环与标志位)
题目要求:输出区间 [2, 30] 内的所有素数(质数)。素数定义为在大于 1 的自然数中,除了 1 和它本身以外不再有其他因数的数。
解题分析:
- 外层循环遍历候选数字
num,从 2 到 30。注意包含 30 时右边界应设置为 31:range(2, 31)。 - 内层循环尝试寻找因数
factor,范围为range(2, int(num ** 0.5) + 1)。只需检测到数字的平方根即可,能显著减少检查次数。 - 一旦检测到
num % factor == 0,说明不是素数,立即使用break终止内层检查。
# 练习题 5 参考代码:双重循环与素数判定
def find_primes(start: int, end: int) -> list[int]:
primes = []
# range 是左闭右开区间,需要包含 end 时必须传入 end + 1
for num in range(start, end + 1):
if num < 2:
continue
is_prime = True
# 寻找因数:检查从 2 到 sqrt(num)
max_factor = int(num ** 0.5)
for factor in range(2, max_factor + 1):
if num % factor == 0:
is_prime = False
break # 找到因数即可确定非素数,提前退出内层循环
if is_prime:
primes.append(num)
return primes
result = find_primes(2, 30)
print(f"2 到 30 之间的素数列表: {result}")
print(f"素数总个数: {len(result)} 个")
素数总个数: 10 个
练习题 6:猜数字游戏与状态哨兵控制(while 循环)
题目要求:预设一个秘密数字 target = 42。模拟用户猜数字的过程,输入序列为 [20, 60, 35, 48, 42]。每次猜错给出“偏大”或“偏小”的提示,统计总共尝试的次数,直到猜中时退出循环并打印统计报表。最多允许尝试 5 次。
# 练习题 6 参考代码:while 循环与状态哨兵
def play_guess_game(target: int, user_inputs: list[int]) -> None:
max_attempts = 5
attempts = 0
input_index = 0
success = False
# 当未达到最大次数且未成功时保持循环
while attempts < max_attempts and input_index < len(user_inputs):
guess = user_inputs[input_index]
attempts += 1
input_index += 1
print(f"第 {attempts} 次尝试,输入数值: {guess}")
if guess == target:
print("恭喜!正确猜中目标数字!")
success = True
break # 达成目标,直接跳出循环
elif guess < target:
print("提示:偏小了。")
else:
print("提示:偏大了。")
if not success:
print("尝试机会用尽,游戏结束。")
else:
print(f"游戏通关!共耗费 {attempts} 次猜测。")
play_guess_game(42, [20, 60, 35, 48, 42])
提示:偏小了。
第 2 次尝试,输入数值: 60
提示:偏大了。
第 3 次尝试,输入数值: 35
提示:偏小了。
第 4 次尝试,输入数值: 48
提示:偏大了。
第 5 次尝试,输入数值: 42
恭喜!正确猜中目标数字!
游戏通关!共耗费 5 次猜测。
四、三大语法要素综合实战演练
在实际工程代码中,变量、条件分支与循环往往交织在一起。下面通过一个综合练习题,展示如何将状态管理、输入检查、业务分流与交互循环有机结合。
综合练习题:简易控制台银行账户交易系统
题目要求:
- 维护一个账户初始余额变量
balance = 1000.0; - 提供菜单指令:
1: 查询余额、2: 存款、3: 取款、4: 退出; - 存款时金额必须大于 0;取款时金额必须大于 0 且不能超过当前余额;
- 循环接收操作序列,若输入无效指令需给出警告提示,输入
4时打印总结并退出循环。
# 综合练习题参考代码:控制台银行账户交易系统
def run_bank_system(mock_actions: list[tuple[str, float]]) -> None:
balance = 1000.0 # 核心状态变量:账户余额
transaction_count = 0 # 统计成功交易笔数
print("=== 欢迎进入简易银行交易系统 ===")
for command, amount in mock_actions:
print(f"\n[执行指令] 选择菜单: {command}")
# 指令分流处理
if command == "1":
print(f"当前账户余额: {balance:.2f} 元")
elif command == "2":
if amount <= 0:
print("操作失败:存款金额必须大于 0 元!")
continue # 跳过当前交易的后续操作
balance += amount
transaction_count += 1
print(f"存款成功!存入: {amount:.2f} 元,最新余额: {balance:.2f} 元")
elif command == "3":
if amount <= 0:
print("操作失败:取款金额必须大于 0 元!")
continue
if amount > balance:
print(f"操作失败:余额不足!当前可用余额仅 {balance:.2f} 元")
continue
balance -= amount
transaction_count += 1
print(f"取款成功!取出: {amount:.2f} 元,最新余额: {balance:.2f} 元")
elif command == "4":
print("收到退出指令,正在安全登出系统...")
break # 终止外层交互循环
else:
print("未知指令代码,请输入有效的菜单编号 (1-4)!")
print("\n=== 会话结束 ===")
print(f"最终账户余额: {balance:.2f} 元,本次共完成 {transaction_count} 笔有效交易。")
# 模拟用户连续操作数据
actions = [
("1", 0.0), # 查询
("2", 500.0), # 存款 500
("3", 2000.0), # 取款 2000 (超额失败)
("3", 300.0), # 取款 300 (成功)
("9", 0.0), # 无效指令
("4", 0.0) # 退出
]
run_bank_system(actions)
[执行指令] 选择菜单: 1
当前账户余额: 1000.00 元
[执行指令] 选择菜单: 2
存款成功!存入: 500.00 元,最新余额: 1500.00 元
[执行指令] 选择菜单: 3
操作失败:余额不足!当前可用余额仅 1500.00 元
[执行指令] 选择菜单: 3
取款成功!取出: 300.00 元,最新余额: 1200.00 元
[执行指令] 选择菜单: 9
未知指令代码,请输入有效的菜单编号 (1-4)!
[执行指令] 选择菜单: 4
收到退出指令,正在安全登出系统...
=== 会话结束 ===
最终账户余额: 1200.00 元,本次共完成 2 笔有效交易。
五、核心知识总结与高频易错点归纳
为了在日常编写代码时少走弯路,下表总结了初学者在面对变量、循环与条件判断时最容易触碰的语法陷阱及检查清单:
| 语法要素 | 高频易错现象 | 底层原因剖析 | 标准规范写法 |
|---|---|---|---|
| 变量与类型 | TypeError: can only concatenate str to str |
Python 为强类型语言,字符串与数值之间不支持隐式自动拼接 | 使用 f-string:f"结果: {val}" 或显式 str(val) 转换 |
| 条件判断 | 所有分支都不命中,或命中非预期宽松分支 | 条件排序颠倒(宽泛条件写在严格条件前)或区间未闭合 | 分支遵循由苛刻到宽松依次排列,先排查异常边界值 |
| for 循环 | 总循环次数比预期少 1 次(边界偏移) | range(start, end) 遵循“左闭右开”规则,不包含 end |
若需要包含第 N 项,范围必须写为 range(1, N + 1) |
| while 循环 | 程序卡死无响应、CPU 占用飙升(死循环) | 循环体内遗漏了对循环判定变量的步进自增或自减操作 | 确保循环体内每一条路径(包含分支)都有推进收敛的逻辑 |
- 先画数据流再编码:对于稍微复杂的多重循环或分支,先用一张纸列出各变量在每一次循环开始和结束时的预期数值。
- 检验极端边界值:在条件判断中,主动测试
0、-1、None、空字符串以及刚好落在区间的边界值(如刚好60分)。 - 优先选择
for替代while:在迭代范围确定的情况下,优先选用自带步进保护的for...in range(...),天然免疫步进缺失引起的死循环。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









