第 1 周:程序、变量与条件
本周从第一条可运行语句开始。目标不是背语法,而是能预测程序按什么顺序执行、每一步数据怎样变化,以及条件为什么进入某个分支。
建议用时:8-10 小时。
本周目标#
学完本周,你应该能够:
- 按从上到下的顺序解释一段简单程序。
- 创建变量,判断常见数据类型,并完成必要的类型转换。
- 正确使用算术、比较、逻辑和赋值运算符。
- 使用
f-string、format()和%三种方式格式化输出。 - 使用
if、elif、else完成多分支判断。 - 阅读并区分缩进、名称、类型和值错误。
- 独立完成成绩等级、温度换算和三角形判断。
1.1 程序是什么#
Python 程序由一条条语句组成。程序通常从上到下执行,遇到条件语句时只进入符合条件的分支。
print("开始")
score = 86
print("分数是", score)
print("结束")
运行结果是:
开始
分数是 86
结束
三条最基本的规则#
- Python 区分大小写,
Score、score和SCORE是三个不同名称。 - 普通语句要独占一行,行首空格决定它属于哪个代码块。
#后面的内容是注释,不会影响程序结果。
# 计算总价
price = 12.5
count = 3
total = price * count
print(total) # 37.5
注释适合说明原因。不要把每一行代码机械地翻译成中文。
执行顺序要和纸面推演一致#
阅读代码时,不要一眼看完整段后猜结果。准备一张表,逐行记录变量当前值:
| 执行到 | price |
count |
total |
屏幕输出 |
|---|---|---|---|---|
| 第 2 行后 | 12.5 | 未定义 | 未定义 | 无 |
| 第 3 行后 | 12.5 | 3 | 未定义 | 无 |
| 第 4 行后 | 12.5 | 3 | 37.5 | 无 |
| 第 5 行后 | 12.5 | 3 | 37.5 | 37.5 |
这种“变量跟踪表”是后续推演循环、排序和函数调用的基础。
1.2 变量、值与类型#
变量可以理解成“名字指向一个值”。赋值语句不是数学等式。
x = 5
x = x + 1
print(x) # 6
第二行的含义是:先计算右边的 x + 1,得到 6,再让左边的名称 x 指向 6。
同一个变量可以先后指向不同类型的值:
value = 10
print(type(value).__name__) # int
value = "10"
print(type(value).__name__) # str
常见基本类型#
| 类型 | 含义 | 例子 | type(x).__name__ |
|---|---|---|---|
int |
整数 | 7、-3、0 |
int |
float |
浮点数 | 3.14、2.0、1e3 |
float |
str |
字符串 | "Python"、""、'7' |
str |
bool |
布尔值 | True、False |
bool |
NoneType |
表示“没有值” | None |
NoneType |
判断类型可以用:
age = 16
height = 1.68
name = "小林"
passed = True
print(type(age).__name__) # int
print(type(height).__name__) # float
print(type(name).__name__) # str
print(type(passed).__name__) # bool
print(type(None).__name__) # NoneType
id 是什么#
id(x) 返回对象在当前运行中的身份标识。它主要用来说明两个名称是否指向同一个对象,不等同于比较值。
a = [1, 2]
b = a
c = [1, 2]
print(a == b) # True,内容相同
print(a == c) # True,内容相同
print(a is b) # True,指向同一对象
print(a is c) # False,分别是两个列表
不要用 id 判断两个值是否相等。比较内容使用 ==;判断是否为同一个对象使用 is。考试中若要求输出 id,通常只考“两个名称是否指向同一对象”或“是否重新创建对象”。
变量命名#
Python 常用命名风格:
- 普通变量和函数使用小写下划线:
student_name、calculate_total。 - 类名使用大驼峰:
Student、BookRecord。 - 常量使用全大写:
MAX_SCORE。
比赛中如果题目已经给出 findMax、searchAll 这样的驼峰名称,要保留题目名称。平时优先使用符合 Python 习惯的 snake_case,同一份程序内不要频繁混用风格。
名称应当表达含义:
# 较好
math_score = 88
# 不推荐
a = 88
1.3 输入、转换与输出#
input() 会读取一行文字,返回值永远是字符串。
name = input("请输入姓名:")
print("你好," + name)
如果需要计算,必须先转换类型:
age_text = input("请输入年龄:")
age = int(age_text)
print(age + 1)
直接写 age_text + 1 会产生 TypeError,因为字符串和整数不能相加。
常用转换#
print(int("25")) # 25
print(int(3.9)) # 3,向零截断
print(float("2.5")) # 2.5
print(str(100)) # "100"
print(bool(0)) # False
print(bool(1)) # True
print(bool("")) # False
print(bool("0")) # True,非空字符串
int("3.5") 会报 ValueError,因为字符串本身不是整数格式。先把 "3.5" 转成 float,再视需求转成 int。
三种格式化输出#
题目常要求固定文字和变量一起输出。下面三种方式都要认识。
方式一:f-string#
name = "李雨"
score = 91
print(f"{name}的成绩是{score}分")
结果:
李雨的成绩是91分
保留两位小数:
rate = 0.875
print(f"{rate:.2f}") # 0.88
方式二:format()#
name = "李雨"
score = 91
print("{}的成绩是{}分".format(name, score))
print("{0}得到{1:.1f}分".format(name, score))
方式三:百分号格式#
print("%s的成绩是%d分" % ("李雨", 91))
print("%.2f" % 0.875) # 0.88
print() 的 sep 和 end#
print("2026", "10", "26", sep="-") # 2026-10-26
print("第一行", end=" ")
print("第二行")
结果:
2026-10-26
第一行 第二行
sep 控制多个参数之间的分隔符,end 控制输出结尾。没有指定时,sep 是空格,end 是换行。
1.4 运算符#
算术运算符#
| 运算符 | 含义 | 例子 | 结果 |
|---|---|---|---|
+ |
加或拼接 | 7 + 2 |
9 |
- |
减 | 7 - 2 |
5 |
* |
乘或重复 | 7 * 2 |
14 |
/ |
除法 | 7 / 2 |
3.5 |
// |
整除 | 7 // 2 |
3 |
% |
取余数 | 7 % 2 |
1 |
** |
幂 | 3 ** 2 |
9 |
注意:/ 的结果总是浮点数,即使正好除尽:
print(8 / 2) # 4.0
print(type(8 / 2).__name__) # float
整数和浮点数混合运算,结果通常是浮点数:
print(5 + 2.0) # 7.0
字符串使用 + 表示拼接,使用 * 表示重复:
print("Py" + "thon") # Python
print("ab" * 3) # ababab
运算优先级#
常见顺序是:
- 括号。
- 幂
**。 - 正负号。
- 乘、除、整除、取余。
- 加、减。
- 比较运算。
not。and。or。
不确定时加括号。括号不会扣分,错误优先级会改变结果。
print(2 + 3 * 4) # 14
print((2 + 3) * 4) # 20
print(2 ** 3 ** 2) # 512,幂从右向左结合
赋值运算符#
x = 10
x += 3 # 等价于 x = x + 3
x -= 2
x *= 4
x //= 2
print(x) # 22
手推时每次只改一个值:
| 语句后 | x |
|---|---|
x = 10 |
10 |
x += 3 |
13 |
x -= 2 |
11 |
x *= 4 |
44 |
x //= 2 |
22 |
常见算术错误#
# print(5 / 0) # ZeroDivisionError
# print("5" + 2) # TypeError
# print(int("2.5")) # ValueError
1.5 布尔值与条件#
条件表达式的结果是 True 或 False。
比较运算符#
| 运算符 | 含义 |
|---|---|
== |
等于 |
!= |
不等于 |
> |
大于 |
< |
小于 |
>= |
大于或等于 |
<= |
小于或等于 |
= 是赋值,== 是比较。这是最容易混淆的两个符号。
逻辑运算符#
and:两边都为真,结果才为真。or:至少一边为真,结果就为真。not:取反。
score = 82
attendance = 0.95
print(score >= 60 and attendance >= 0.8) # True
print(score >= 90 or attendance >= 0.9) # True
print(not score >= 90) # True
Python 会进行短路判断:and 左边为假时,不再计算右边;or 左边为真时,不再计算右边。基础题先按普通逻辑理解,遇到函数调用或异常时才需要关注短路。
if、elif、else#
score = 86
if score >= 90:
level = "优秀"
elif score >= 80:
level = "良好"
elif score >= 60:
level = "及格"
else:
level = "不及格"
print(level) # 良好
执行规则:
- 从上往下检查条件。
- 进入第一个为真的分支。
- 该分支执行完后,跳过同组后面的分支。
- 如果所有
if/elif都为假,才进入else。
因此上面的 score >= 80 不需要再写 score < 90,因为程序能到这里就说明前面的 score >= 90 已经不成立。
缩进不是装饰#
if score >= 60:
print("及格")
print("可以进入下一阶段")
print("程序结束")
前三行中的两个 print 属于条件分支;最后一个 print 在分支外,无论条件真假都会执行。
嵌套条件#
is_member = True
amount = 120
if is_member:
if amount >= 100:
print("会员满减 20 元")
else:
print("会员未满 100 元")
else:
print("非会员")
嵌套层数最好不要超过两三层。能用 and 写清的条件,优先组合起来。
1.6 读懂报错与独立调试#
报错不是失败信号,而是定位线索。先读最后一行异常类型,再往上看文件名、行号和出错语句。
| 报错 | 常见含义 | 第一检查点 |
|---|---|---|
SyntaxError |
语法不完整 | 冒号、括号、引号是否配对 |
IndentationError |
缩进不一致 | 是否统一使用 4 个空格 |
NameError |
使用了未定义名称 | 拼写、大小写、赋值顺序 |
TypeError |
类型不支持该操作 | 是否把字符串当数字 |
ValueError |
类型正确但内容无法转换 | int() 中是否不是整数 |
ZeroDivisionError |
除以零 | 除数是否可能为 0 |
例如:
age_text = "16"
print(age_text + 1)
会产生 TypeError。修复方式是 int(age_text) + 1。
三段式排错法#
- 确定位置:报错指向哪一行?
- 确定值:这一行用到的每个变量现在是什么类型、什么值?
- 最小修改:只改一处,再运行,观察是否解决。
可以在关键语句前打印中间值:
score = 78
bonus = 5
final_score = score + bonus
print("调试:final_score =", final_score)
调试完成后删除临时输出,避免最终答案多出不该有的内容。
如果使用带断点的编辑器,可以在目标行暂停程序,再逐行执行,观察变量面板。断点的作用是让程序停下来检查状态,不是自动修复错误。
1.7 本周作品一:成绩等级#
需求#
输入一个整数成绩:
- 90-100:优秀。
- 80-89:良好。
- 60-79:及格。
- 0-59:不及格。
- 其他成绩:输出“成绩无效”。
拆步骤#
- 读取成绩。
- 转换为整数。
- 先判断成绩是否在 0-100。
- 再按从高到低的顺序判断等级。
- 输出结果。
参考程序#
score_text = input("请输入成绩:")
score = int(score_text)
if score < 0 or score > 100:
print("成绩无效")
elif score >= 90:
print("优秀")
elif score >= 80:
print("良好")
elif score >= 60:
print("及格")
else:
print("不及格")
必测数据#
| 输入 | 期望输出 | 测试重点 |
|---|---|---|
| 100 | 优秀 | 上边界 |
| 90 | 优秀 | 等级边界 |
| 89 | 良好 | 等级边界下方 |
| 60 | 及格 | 及格边界 |
| 59 | 不及格 | 不及格边界上方 |
| 0 | 不及格 | 下边界 |
| -1 | 成绩无效 | 非法输入 |
| 101 | 成绩无效 | 非法输入 |
1.8 本周作品二:温度换算#
摄氏度和华氏度的换算关系:
华氏度 = 摄氏度 * 9 / 5 + 32
摄氏度 = (华氏度 - 32) * 5 / 9
下面的程序把摄氏度转换为华氏度,保留一位小数:
celsius = float(input("请输入摄氏度:"))
fahrenheit = celsius * 9 / 5 + 32
print(f"{celsius:.1f} 摄氏度 = {fahrenheit:.1f} 华氏度")
输入 25 时,输出是:
25.0 摄氏度 = 77.0 华氏度
注意:如果题目指定输出格式,就严格按题目中的空格、冒号、单位和换行输出。
1.9 本周作品三:三角形判断#
三条边能组成三角形的条件是:
- 三条边都大于 0。
- 任意两边之和大于第三边。
a = float(input("请输入第一条边:"))
b = float(input("请输入第二条边:"))
c = float(input("请输入第三条边:"))
if a <= 0 or b <= 0 or c <= 0:
print("边长必须大于 0")
elif a + b > c and a + c > b and b + c > a:
print("可以组成三角形")
else:
print("不能组成三角形")
测试数据:
a |
b |
c |
期望 |
|---|---|---|---|
| 3 | 4 | 5 | 可以组成三角形 |
| 1 | 1 | 1 | 可以组成三角形 |
| 1 | 2 | 3 | 不能组成三角形 |
| 0 | 4 | 5 | 边长必须大于 0 |
进一步变式:判断等边、等腰、普通三角形时,先确保能组成三角形,再判断边的关系。浮点数不要随手用 == 比较,正式题如果都是整数,可以保留整数输入。
1.10 独立练习#
先关闭答案,在纸上推演,再运行验证。
A. 快速判断题#
type(int("12") + 3.0).__name__是什么?x = 5; x //= 2; x **= 2后,x是多少?"7" + "3"与"7" * 3分别是什么?bool("0")是True还是False?判断成绩是否合法,应该写
0 <= score <= 100吗?score = 85时,下面的程序输出什么?if score >= 60: print("及格") if score >= 80: print("良好")
B. 编程题#
- 输入两个整数,输出它们的和、差、积、商和余数。
- 输入一个整数,判断它是奇数还是偶数。
- 输入三个整数,输出最大值。要求不使用
max()。 - 输入用户年龄,判断是否满足
12 <= age <= 18。 - 输入年月,按“2026 年 10 月”的格式输出。
- 输入一个三位整数,分别输出百位、十位和个位数字。
- 输入三个边长,输出是否能组成三角形。
1.11 练习答案与解释#
A. 快速判断题答案#
float。int("12")得到 12,整数与浮点数相加得到15.0。4。5 // 2是 2,随后2 ** 2是 4。分别是
"73"和"777"。两个字符串使用+表示拼接,使用*表示重复。True。字符串"0"不为空,所以它的布尔值为真。可以。这是 Python 允许的连续比较,等价于
0 <= score and score <= 100。输出两行:
及格 良好这是两个独立的
if,不是if/elif,所以两个分支都可能执行。
B. 编程题参考答案#
基本运算:
a = int(input()) b = int(input()) print(a + b) print(a - b) print(a * b) print(a / b) print(a % b)除数
b不能为 0。正式题如果可能出现 0,需要先判断再计算。奇偶判断:
number = int(input()) if number % 2 == 0: print("偶数") else: print("奇数")三个数最大值:
a = int(input()) b = int(input()) c = int(input()) if a >= b and a >= c: maximum = a elif b >= a and b >= c: maximum = b else: maximum = c print(maximum)年龄范围:
age = int(input()) if 12 <= age <= 18: print("是青少年") else: print("不在范围内")格式化输出:
year = int(input()) month = int(input()) print(f"{year} 年 {month} 月")三位数拆位:
number = int(input()) hundreds = number // 100 tens = number // 10 % 10 ones = number % 10 print(hundreds, tens, ones)三角形判断参考 1.9 节。
1.12 常见错误清单#
- 把
=当比较,或在条件里用了赋值。 - 忘记转换
input()的字符串结果。 - 在
if、elif、else后面漏写冒号。 - 缩进数量不一致,或条件外语句误缩进。
- 使用中文标点作为代码符号。
- 把
3.0 // 2误认为字符串操作。 - 多个独立
if和elif混用,导致执行了不止一个分支。 - 输入
100但输出格式多一个空格或缺少单位。
1.13 过关检查#
不看书完成以下检查,全部通过后再进入第 2 周:
- 能解释
/、//、%、**的区别。 - 能说出 5 种常见类型及
type(x).__name__的结果。 - 能把字符串输入转换成整数并完成计算。
- 能使用三种格式化方式输出固定小数位。
- 能区分
if与elif的执行差异。 - 能阅读
NameError、TypeError和ValueError并说出原因。 - 能不运行代码,正确推演一段包含 6 个分支的等级判断程序。
- 独立写出成绩等级和三角形判断,且通过边界测试。
- 错题记录中至少有一条完整的“报错原文、原因、修改方式”。
第 2 周开始前,把本周代码中至少一个作品关掉资料重写一次。重写不是背代码,而是重新按“输入、处理、输出”设计程序。