目录
- 3.1 布尔值与比较运算
- 3.2 逻辑运算:and、or、not
- 把条件翻译成代码
- 短路求值
- and / or 的返回值不一定是布尔值
- 3.3 if / elif / else
- 嵌套 if
- 空代码块用 pass 占位
- 3.4 直接判断「真假」
- 3.5 三元表达式
- 3.6 while 循环:条件为真就一直做
- 死循环与如何避免
- while True + break:菜单式程序的标准写法
- 累加与计数模板
- 3.7 for 循环:遍历一个序列
- range():生成一串整数
- 需要下标时用 enumerate
- 3.8 break、continue 和循环的 else
- 3.9 嵌套循环
- 经典练习:九九乘法表
- 嵌套循环里的 break 只跳一层
- 3.10 常见坑清单
- 3.11 小结
- 3.12 课后练习
- 参考答案
3.1 布尔值与比较运算
程序要做判断,判断的结果只有两种:True(真)和 False(假)。
>>> 3 > 2
True
>>> 3 > 5
False
六个比较运算符:
| 运算符 | 含义 | 例子 | 结果 |
|---|---|---|---|
== |
等于 | 3 == 3 |
True |
!= |
不等于 | 3 != 3 |
False |
> |
大于 | 3 > 2 |
True |
< |
小于 | 3 < 2 |
False |
>= |
大于等于 | 3 >= 3 |
True |
<= |
小于等于 | 3 <= 2 |
False |
⚠️ 最高频错误:把
==(比较)写成=(赋值)。if x = 3:会直接报SyntaxError,这也算好事——至少它不会默默做错事。
Python 支持链式比较,可以直接写数学里的区间:
>>> 1 < 2 < 3
True
>>> 1 < 3 < 2
False # 等价于 1 < 3 and 3 < 2
>>> age = 25
>>> 18 <= age < 60
True
3.2 逻辑运算:and、or、not
>>> True and False
False
>>> True or False
True
>>> not True
False
真值表:
| A | B | A and B |
A or B |
|---|---|---|---|
| True | True | True | True |
| True | False | False | True |
| False | True | False | True |
| False | False | False | False |
and 要求两边都真,or 只要一边真,not 取反。
把条件翻译成代码
age = 25
has_ticket = True
# 「年龄满 18 且持有门票」
if age >= 18 and has_ticket:
print("可以入场")
# 「年龄不满 18,或者没有门票」
if age < 18 or not has_ticket:
print("不能入场")
短路求值
and 和 or 不一定会看完右边——结果已经确定时立刻停止。这既是性能优化,也是防错手段:
x = 0
# 先判断 x != 0,为 False 时右边的除法不会执行,避免除以 0 崩溃
if x != 0 and 10 / x > 1:
print("成立")
else:
print("不成立") # 输出:不成立
name = input("名字:") or "匿名用户" # 输入为空时用默认值
上面这行利用了「or 返回第一个为真的操作数」,是 Python 里很常见的写法。不过对初学者来说,写成 if not name: name = "匿名用户" 更直白。
and / or 的返回值不一定是布尔值
>>> 0 and "hello"
0
>>> 3 and "hello"
'hello'
>>> "" or "默认"
'默认'
and 返回第一个假值(全真则返回最后一个),or 返回第一个真值(全假则返回最后一个)。知道这个规则,上面 or "匿名用户" 的写法就说得通了。
3.3 if / elif / else
score = 85
if score >= 90:
print("优秀")
elif score >= 75:
print("良好")
elif score >= 60:
print("及格")
else:
print("不及格")
输出:
良好
三条规则必须记住:
-
每个条件后面有冒号
:,这是很多新手第一个SyntaxError。 -
代码块靠缩进划分,通常是 4 个空格。同一块内缩进必须一致。
-
从上往下依次判断,命中一个就跳出整个结构,后面即使条件也成立也不会执行。
x = 100 if x > 0: print(“正数”) elif x > 50: # 永远不会执行到,因为 x > 0 已经命中了 print(“大于 50”)
所以 elif 的顺序很重要:范围判断要从窄到宽,或者从宽到窄统一排列,别让宽条件把窄条件吃掉。
嵌套 if
if age >= 18:
if has_ticket:
print("入场")
else:
print("先买票")
else:
print("未成年")
嵌套超过两层就该考虑重构(用 and 合并条件、提前 return、拆函数)。平铺的代码永远比嵌套的好读。
空代码块用 pass 占位
if score >= 60:
pass # 还没想好写什么,先占位,否则 IndentationError
else:
print("补考")
3.4 直接判断「真假」
if 后面不一定非得是比较表达式,任何值都能判断真假:
items = []
if items: # 空列表为假
print("有内容")
else:
print("空列表") # 输出这个
name = ""
if not name:
print("名字为空")
Python 的假值只有这几个:False、None、0、0.0、""、[]、()、{}、set()。其它都是真。
所以下面两种写法等价,但第一种更地道:
if items: # ✅ 推荐
if len(items) > 0: # 😐 能用,但啰嗦
判断 None 时用 is,不要用 ==:
if result is None:
print("没有结果")
is 比较的是「是不是同一个对象」,None 全局只有一个,所以 is None 既准确又更快。
3.5 三元表达式
只有「二选一」时,可以写成一行:
age = 20
status = "成年" if age >= 18 else "未成年"
print(status) # 成年
结构是 值A if 条件 else 值B。读起来像英文:「A,如果条件成立,否则 B」。
不要嵌套三层以上,那种时候老老实实写 if。
3.6 while 循环:条件为真就一直做
count = 1
while count <= 5:
print(count)
count += 1 # 千万别忘这行
输出 1 2 3 4 5,每个一行。
while 的逻辑:检查条件 → 为真则执行循环体 → 回到检查条件 → ……直到条件为假。
死循环与如何避免
# ❌ 死循环:count 永远不变,条件永远为真
count = 1
while count <= 5:
print(count)
按 Ctrl + C 可以强制中断。写 while 时养成习惯,先问自己两个问题:
- 哪个变量控制循环结束?
- 它在循环体里真的被改变了吗?
while True + break:菜单式程序的标准写法
while True:
cmd = input("输入命令(q 退出):")
if cmd == "q":
break
print(f"你输入了:{cmd}")
print("程序结束")
这种「不知道要循环多少次,靠条件退出」的场景,用 while True + break 最清晰。
累加与计数模板
total = 0
i = 1
while i <= 100:
total += i
i += 1
print(total) # 5050
「初始化累加器 → 循环里更新 → 循环外使用」是所有统计类代码的骨架。
3.7 for 循环:遍历一个序列
for 用来「把一堆东西挨个处理一遍」:
for ch in "Python":
print(ch)
输出 P y t h o n。
fruits = ["苹果", "香蕉", "橘子"]
for fruit in fruits:
print(f"我喜欢吃{fruit}")
比 while 省事:不需要索引、不需要手动加一、不会越界。能用 for 就别用 while。
range():生成一串整数
range(5) # 0 1 2 3 4 左闭右开,不含 5
range(1, 5) # 1 2 3 4
range(0, 10, 2) # 0 2 4 6 8 步长 2
range(5, 0, -1) # 5 4 3 2 1 倒着数
for i in range(1, 6):
print(i, end=" ") # 1 2 3 4 5
⚠️ off-by-one 错误:
range(1, 5)不含 5。要「1 到 5」必须写range(1, 6)。这是全世界程序员都犯过的错,写循环时念一遍「左闭右开」。
需要下标时用 enumerate
names = ["小明", "小红", "小刚"]
for i, name in enumerate(names, start=1):
print(f"{i}. {name}")
输出:
1. 小明
2. 小红
3. 小刚
别写 for i in range(len(names)),再用 names[i] 取值——啰嗦且容易越界。
3.8 break、continue 和循环的 else
| 关键字 | 作用 |
|---|---|
break |
立刻跳出当前整个循环 |
continue |
跳过本轮剩余代码,直接进入下一轮 |
pass |
什么也不做,纯占位 |
# break:找到就停
for n in range(2, 100):
if n % 7 == 0:
print(f"第一个能被 7 整除的数是 {n}")
break
# continue:跳过偶数
for i in range(1, 11):
if i % 2 == 0:
continue
print(i, end=" ") # 1 3 5 7 9
for ... else 是个冷门但好用的语法:循环正常跑完(没被 break)时执行 else。
target = 17
for n in range(2, int(target ** 0.5) + 1):
if target % n == 0:
print(f"{target} 不是质数")
break
else:
print(f"{target} 是质数")
如果觉得 else 容易误解,可以改用标志变量,效果一样,只是多两行。
3.9 嵌套循环
外层跑一次,内层跑一整轮:
for i in range(1, 4):
for j in range(1, 4):
print(f"({i},{j})", end=" ")
print() # 每行结束换行
输出:
(1,1) (1,2) (1,3)
(2,1) (2,2) (2,3)
(3,1) (3,2) (3,3)
经典练习:九九乘法表
for i in range(1, 10):
for j in range(1, i + 1): # 内层只跑到 i,形成三角
print(f"{j}×{i}={i * j}", end="\t")
print()
输出前两行:
1×1=1
1×2=2 2×2=4
\t 是制表符,用来对齐列。如果中文列宽对不齐,可以改用 f-string 的宽度控制 f"{...:<8}"。
嵌套循环里的 break 只跳一层
for i in range(3):
for j in range(3):
if j == 1:
break # 只跳出内层,外层继续
print(i, j)
输出 0 0、1 0、2 0。要一次跳出两层,常见做法是加标志位或用函数 return(第 5 课)。
3.10 常见坑清单
| 现象 | 原因 | 修法 |
|---|---|---|
SyntaxError: expected ':' |
if/for/while 后面漏冒号 |
补 : |
IndentationError |
缩进不一致,Tab 和空格混用 | 统一 4 空格 |
| 程序卡住不动 | while 条件永远为真 |
检查控制变量是否更新 |
| 循环少跑/多跑一次 | range 左闭右开 |
终点写「实际值 + 1」 |
| 条件永远不成立 | 用了 = 而不是 ==,或类型不匹配("18" == 18 为 False) |
检查运算符和类型 |
| 判断浮点数相等失败 | 0.1 + 0.2 == 0.3 为 False |
用 round 或误差范围 |
另外两个隐蔽的坑:
# 坑一:字符串和数字比较,Python 3 直接报错,别指望它「自动转换」
>>> "18" > 9
TypeError: '>' not supported between instances of 'str' and 'int'
# 坑二:浮点数做循环条件,可能永远差一点点
>>> i = 0.0
>>> while i != 1.0: # 危险!0.1 累加十次不等于 1.0
... i += 0.1
浮点数循环改用整数计数:
for k in range(10):
i = k / 10
3.11 小结
- 比较得到布尔值,
==是比较,=是赋值 and/or短路求值,可以拿来防除零、设默认值if / elif / else从上往下命中即止,缩进决定归属- 假值:
False、None、0、""、[]、{} - 次数已知用
for,条件驱动用while range左闭右开;要下标用enumeratebreak跳一层,continue跳一轮- 嵌套循环内层跑满,外层才走一步
3.12 课后练习
练习 1 输入一个整数,判断它是正数、负数还是零。
练习 2 输入年份,判断是否闰年。规则:能被 4 整除但不能被 100 整除,或者能被 400 整除。
练习 3 打印 1~100 中所有能被 3 或 5 整除的数,每行 5 个。
练习 4 FizzBuzz:1~100,能被 3 整除打印 Fizz,能被 5 整除打印 Buzz,能同时被 3 和 5 整除打印 FizzBuzz,其余打印数字本身。
练习 5 猜数字游戏:程序随机想一个 1~100 的数,用户反复猜,程序提示「大了」或「小了」,猜对时输出猜了几次。
练习 6 打印如下图形(高度由用户输入,这里以 4 为例):
*
**
***
****
参考答案
练习 1
num = float(input("输入一个数:"))
if num > 0:
print("正数")
elif num < 0:
print("负数")
else:
print("零")
练习 2
year = int(input("年份:"))
if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
print(f"{year} 是闰年")
else:
print(f"{year} 是平年")
括号很关键。and 的优先级高于 or,不加括号时结果其实一样,但加上括号能让读代码的人立刻看懂逻辑分组。
练习 3
count = 0
for i in range(1, 101):
if i % 3 == 0 or i % 5 == 0:
print(f"{i:>4}", end="")
count += 1
if count % 5 == 0:
print() # 每 5 个换一行
练习 4
for i in range(1, 101):
if i % 15 == 0:
print("FizzBuzz")
elif i % 3 == 0:
print("Fizz")
elif i % 5 == 0:
print("Buzz")
else:
print(i)
顺序不能反:如果先判断 i % 3 == 0,那 15 的倍数会先命中 Fizz,永远输出不到 FizzBuzz。这是「条件顺序决定结果」的典型案例。
练习 5
import random # import 的用法第 7 课细讲,这里照抄即可
target = random.randint(1, 100)
count = 0
while True:
guess = int(input("猜一个 1-100 的数:"))
count += 1
if guess < target:
print("小了")
elif guess > target:
print("大了")
else:
print(f"猜对了!你用了 {count} 次")
break
练习 6
n = int(input("高度:"))
for i in range(1, n + 1):
print("*" * i)
"*" * 3 得到 "***",字符串乘法是打印图形最省事的工具。想打印居中的金字塔,改成:
for i in range(1, n + 1):
print(" " * (n - i) + "*" * (2 * i - 1))
评论
评论区即 对应 issue 的讨论串,登录 GitHub 即可留言。