10-if 条件判断
在 Python 中,代码的缩进和条件判断是最基础也是最关键的语法概念。接下来,我们将逐步讲解这两部分的知识,并通过详细实例帮助你理解和掌握它们。
1. 缩进
Python 是使用 四个空格或者一个 Tab来表示缩进都可以,但不要混用 。
Python 采用缩进来区分代码块,而不是像其他语言那样使用大括号 {}
。需要注意的是:
- 缩进方式:可以使用 四个空格 或 一个 Tab 来表示缩进。
- 注意事项:不要混用空格和 Tab,否则会导致解释器报错。(因为是写成书,我没法带你演示这个报错,这个问题有些学生经常遇到,代码、语法全部正确,就是运行会报错。找半天都没找出来,故而你一定要切记:空格和 Tab 缩进不要混用!)
- 相同缩进位置的代码表示他们是同一个代码块。
提示:同一层级的代码必须有相同的缩进,否则会引起逻辑错误或语法错误。
下面是一个简单示例,展示如何正确使用缩进:
condition = True
while condition:
a = 1
if a < 10:
print(f"a:>>>{a}")
混用会报错!
condition = True
a = 1
while condition:
if a < 6:
print(f"a:>>>{a}")
else:
condition = False
a += 1
在上面的代码中:
while condition:
后面缩进的部分是while
循环的内容(代码);if a < 6:
后面同一级缩进的部分是if
条件成立时会执行的内容(代码);else:
后面是 if 不执行时,执行 else 时会执行的内容(代码);a += 1
和代码if a < 6:
、else:
都属于同级代码;
只要你保持同一级缩进一致,Python 就能正确地识别哪段代码属于哪个块。可如果你混用空格和 Tab,则会报错,建议大家始终统一使用一种缩进方式。
我下面使用 Sublime Text3 进行代码截图,因为 Sublime Text3 在全选代码时,会显示当前代码是以什么为缩进。空格缩进的代码前面会有很多点组成缩进,我尽可能演示给你看。如下图:
接下来,我将使用 Sublime Text3 对代码进行截图展示。因为在全选代码时,Sublime Text3 会直观地显示当前采用的缩进方式——例如,使用空格缩进时,代码前会显示一串点以示区分。使用 Tab 缩进时,代码前会显示直线以示区分。我会尽量为你演示这一效果,如下图所示:

可以看见上面的代码中 if a < 6:
前面和里面代码 print(f”a:>>>{a}”)
前的缩进都是以一串点来显示的,表明当前
可以看到,在上图的代码中,从 while condition:
(第 3 行)到内部的 if a < 6:
、print(f"a:>>>{a}")
、else:
、condition = False
以及 a += 1
等语句前,都以一串点来表示缩进。这说明 Sublime Text 3 检测到的所有这些缩进都是由空格组成的。并且此时,代码成功运行并输出结果。
接下来,我们代码全部改成 Tab 缩进并运行看看:

在这张使用 Tab 缩进的截图中,Sublime Text 3 会在代码前方显示一条横线来表示每一级缩进。你可以从 while condition:
到 if a < 6:
、print(f"a:>>>{a}")
、else:
等各处看到这些横线,说明这里的缩进方式是通过 Tab 实现的。代码也是正常运行并输出。
现在,我们来看看因为缩进混用。原本正确的代码,会无法运行报错:

在上图中,我故意把代码print(f"a:>>>{a}")
前面的缩进改成 Tab 键缩进,结果运行时代码直接报错。虽然现在很多代码编辑器会自动统一缩进,但要是在某一时刻实效了呢?所以一定要有缩进相同的意识。
试想一下这个场景:如果你不小心混用了代码缩进,导致代码报错。并且你使用的不是 Sublime Text3 这个编辑器,那你会耗费巨大的时间和精力。就算你去问 AI 还是搜索引擎,你都找不到答案。你甚至不知道怎么怎么去提问吧,所以这个时候你要考虑是不是缩进问题。(当然也有可能其它问题导致代码正确,但是无法运行。)
不知道上面有没有把缩进不同导致的问题,给你讲清楚。多思考多阅读,多尝试!
注意:如果在同一个文件中混用空格和 Tab,就会出现缩进报错!请一定养成统一使用空格或 Tab 的好习惯。
2. 条件判断
条件判断让程序能够根据不同的输入或状态执行不同的代码逻辑。在 Python 中,我们通常使用 if
、elif
和 else
来实现条件判断。
下面的两张示例图形象地展示了一个多重条件判断的思路:如果满足第一条件,就执行某操作;如果不满足,再判断第二条件……依次类推,直到最终得到一个明确的结果。
2.1 条件判断流程图示例
示例图 1

示例图 2

从上面的示例图可以看出:
- 当某个条件(如“明天下不下雨”)为真时,就会执行对应操作(例如“宅在家打游戏”)。
- 如果第一个条件不满足,就检查下一个条件(如“球场开放”),再决定相应的操作。
- 如果所有条件都不满足,则执行默认的处理逻辑(如“去图书馆自习”)。
这些生活中的情境演示,其实与 Python 里的条件判断非常类似:
if
语句判断一个条件;elif
语句判断其他可能性;else
语句在所有条件都不满足时执行。
上面两张图,希望可以让你理解条件判断的真正原理。每个条件判断都会从上到下依次检查,一旦某个条件成立,就执行对应代码块,然后跳过后面的判断(如果使用了 elif
和 else
)。
3. 例子:判断用户输入
下面的例子通过条件判断,根据用户输入的性别显示不同的提示信息:
user_gender = input("请输入您的性别(F/M):")
if user_gender == "F":
print("你是萌妹子")
elif user_gender == "M":
print("你是糙汉子")
else:
print("输入不正确,请输入 F 或 M")
代码解析:
- 当输入为 F 时,程序输出 “你是萌妹子”;
- 当输入为 M 时,程序输出 “你是糙汉子”;
- 如果输入既不是 既不是 F 也不是 M,则提示用户**输入有误**。
注意:在条件判断中,else
后面不跟条件,它表示所有前面条件都不满足时执行的代码块。
如果收到的内容是 F 那么输出 你是萌妹子;否则如果收到的内容是 M 那么输出 你是糙汉子;如果 既不是 F 也不是 M 那么告诉用户 输错了;else 后面不跟条件;
4. 条件判断执行流程细节
下面的代码再次演示如何根据用户输入判断性别。与之前的示例相比,这里我们再次强调条件判断的基本流程和注意事项:
user_gender = input("请输入您的性别(F/M):")
if user_gender == "F":
print("你是萌妹子")
elif user_gender == "M":
print("你是糙汉子")
else:
print("输入不正确,请输入 F 或 M")
重点说明:
elif 就是 else if 的缩写;elif
是else if
的缩写,用于在前面的条件不满足时继续判断;条件判断会从第一个开始判断,直到有一个符合条件的就不继续往下;- 条件判断是从上到下依次进行的,一旦某个条件成立(符合),其后面的条件将不会再被检查;
- 如果没有 else 分支,且前面条件都不符合会输出什么?——这段条件判断语句什么都不会输出。
如果没有else
分支,并且所有条件都不满足,则程序不会有任何输出。
5. 使用多个 elif 来优化决策流程「elif 可以有多个」
在判断时如果有多种条件需要依次检查,可以使用多个 elif
来依次检查。下面这个例子接收用户输入的数字,并根据数值范围输出不同的信息:
# 输入一个数字
number = int(input("请输入一个数字:"))
# 检查数字的范围
if number < 0:
print("这是一个负数")
elif number == 0:
print("数字是零")
elif number > 0 and number <= 10:
print("数字在1到10之间")
elif number > 10 and number <= 20:
print("数字在11到20之间")
elif number > 20 and number <= 30:
print("数字在21到30之间")
else:
print("数字大于30")
在这个示例中,程序会从上到下依次检查每个条件,一旦找到满足的条件,就会执行对应的代码,并跳过后续的判断。
上面的代码还可以写得更简洁一些,例如我们可以直接用区间表达式来判断范围,使条件更直观:
# 输入一个数字
number = int(input("请输入一个数字:"))
# 检查数字的范围
if number < 0:
print("这是一个负数")
elif number == 0:
print("数字是零")
elif 0 < number <= 10:
print("数字在 1 到 10 之间")
elif 10 < number <= 20:
print("数字在 11 到 20 之间")
elif 20 < number <= 30:
print("数字在 21 到 30 之间")
else:
print("数字大于 30")
这种写法不仅更加简洁,而且更容易阅读和理解,特别适合用于判断数值是否在某个区间内。
我们接着思考,上面的代码实现在逻辑上,是最精简的吗?并不是,我们在现实生活中判断性别怎么判断?一个人如果不是男的的,那么她必然是女的是不是。(咱们不考虑其它特殊情况)
再比如,一个人的分数不大于 100,那么肯定是小于 100 的是不是。所以上面代码中,如果不执行 if number < 0
,就代表着 number 肯定是大于 0,在后续的代码中还需要判断 number > 0
吗?——显然是不需要的。
再来一个,上面代码中如果不执行:elif 0 < number <= 10
,意味着什么?——意味着 number 已经是大于 10 的数字,后续就不用再判断 number 是不是大于 10了( 10 < number
)。
悟了吗?学习代码有时候也需要悟一下,这个悟是体现在通过我上面的讲解,你瞬间知道上面的代码应该如何优化了。这个一瞬间称为:悟。当然,也可以说理解了。不过我更喜欢说悟,因为只有你真正感受到那个状态了,你的思维是真正得到了一次提升!
故而,我们的代码可以优化成如下,看之前自己写一下再看我提供的代码:
# 输入一个数字
number = int(input("请输入一个数字:"))
# 检查数字的范围
if number < 0:
print("这是一个负数")
elif number == 0:
print("数字是零")
elif number <= 10:
print("数字在 1 到 10 之间")
elif number <= 20:
print("数字在 11 到 20 之间")
elif number <= 30:
print("数字在 21 到 30 之间")
else:
print("数字大于 30")
上面代码可以成立的最核心点其实就是借助:一组 if...elif...elif...else...
只会执行其中一个。
小贴士:
- 原本的写法是显式地写出了具体的区间范围,而改进之后的写法是依赖条件的“前后顺序”来隐含某些范围。
一组if...elif...else
只会执行其中一个分支。- 一组
if...elif...elif...else...
结构中,只会执行最先匹配到的那个条件块,后续条件将被忽略。
注意⚠️:一组 if...elif...elif...else...
只会执行其中一个。
if if 和 if…elif 区别
6. 理解条件判断:if 连写 vs. if...elif
与连续使用多个独立的 if
语句不同,if...elif
结构会在遇到第一个满足条件的分支后跳出判断过程。我们接下来探究一下,很多人有时会连写 if 的原因以及注意点,而有时却推荐写成 if...elif
是为何。
6.1 连写 if 存在的问题
我们写一个连写 if 的程序,并观察会出现的问题:
score = 85
if score >= 90:
print("优秀")
if score >= 80:
print("良好")
if score >= 60:
print("及格")
else:
print("不及格")
上面的代码运行后会输出什么结果呢,思考一下。会输出如下结果:
良好
及格
解释:
虽然 score = 85
只应该对应一个等级“良好”,但由于多个 if 是独立判断的,程序先判断 score >= 90
发现不符合,则继续判断 score >= 80
虽然成立了并且也执行了。可是下一个依然使用的是 if,所以还是会执行判断 score >= 60
得到的结果也是真(True),因此输出了两个结果。这种情况在实际应用中可能会导致逻辑错误。
在这个示例中,score = 85
其实只应该对应一个等级“良好”。但是,由于使用的是多个独立的 if
语句,程序会依次判断:
if score >= 90:
不满足,跳过。if score >= 80:
满足,执行并打印“良好”。下一个依然是if score >= 60:
,而不是elif
,所以它依旧会进行判断。条件也为真,因此又打印“及格”。
结果,程序最终输出了“良好”和“及格”两个结果,实际却只需要一个等级评价。这就导致了逻辑上的错误或多余的输出。
虽然 score = 85
按照常规理解只对应一个等级“良好”,但上面的代码采用的是多个独立的 if
语句,程序会依次逐个判断每个条件:
- 首先判断
if score >= 90:
,结果是不满足,跳过这个代码块。 - 接着程序继续判断
if score >= 80:
,结果是满足的,执行打印出“良好”。 - 但由于下一个条件依然使用的是单独的
if
,而不是elif
。程序不会因为前面的条件已经满足而停止,而是会继续往下执行判断if score >= 60:
,结果也为真,于是再次执行了打印语句,输出“及格”。
这样一来,出现了两个等级的输出:“良好”和“及格”,这并不是我们真正想要的效果,我们实际上只需要一个等级评价,这就导致了逻辑上的错误或多余的输出,并且在实际应用中可能导致逻辑混乱或错误。
6.2 使用 if...elif...else
结构
score = 85
if score >= 90:
print("优秀")
elif score >= 80:
print("良好")
elif score >= 60:
print("及格")
else:
print("不及格")
输出:
良好
解释:
在 if...elif...else
结构中,程序会从上到下依次判断条件。一旦遇到第一个为真的条件(这里是 score >= 80
),就会执行对应的代码块,并立即跳出整个判断结构,不再判断后续条件,从而保证只输出一个等级。
在使用 if...elif...else
结构时,程序会从上到下依次判断每个条件:
- 首先判断
score >= 90
,结果不满足,于是跳过该代码块,继续向下检查; - 然后判断
score >= 80
,此时条件满足,因此程序立即执行对应的代码块(打印“良好”),并且不再继续向下判断其他剩余条件(比如score >= 60
)。
这样一来,即使后面的条件也成立,程序也不会再执行其他分支,从而确保只输出一个明确的等级结果,避免了像连续使用多个独立的 if
那样可能同时输出多个结果的情况。
6.3 连续 if 和 if…elif…else 该怎么选?
6.3.1 什么时候使用多个独立的 if
当你希望程序对多个条件逐一判断,并且多个条件之间是互相独立、互不影响时,我们就可以使用多个独立的 if
语句。也就是说,每个条件都可能为真,每个分支都可能执行,甚至可能同时执行多个。
举个简单的例子,你知道疫情期间要是不是且定期做核酸检测吧。那时候不仅仅有判断是不是阳了,还需要判断是不是重灾区来的人口,还要看看健康码是不是绿的等情况。我们的程序就可以如下这么写:
你还记得疫情期间,我们是不是经常要定期做核酸检测?当时不仅需要判断一个人是不是阳性(感染病毒了),还得看这个人是不是来自疫情高风险地区,甚至还要检查一下健康码是不是绿码。
这些条件实际上是独立的,因为每个条件都要分别检查,有时候多个条件可能同时满足。程序就可以用多个独立的 if
语句来实现:
is_positive = False # 是否阳性
from_high_risk_area = True # 是否来自高风险地区
is_health_code_green = False # 健康码是否是绿码
# 单独检查是否阳性
if is_positive:
print("⚠️ 你是阳性患者,请立即隔离!")
# 单独检查是否来自高风险地区
if from_high_risk_area:
print("⚠️ 你来自高风险地区,请进行核酸检测并报备!")
# 单独检查健康码是否绿码
if not is_health_code_green:
print("⚠️ 你的健康码不是绿码,暂时无法进入公共场所!")
假设按照上面的情况运行程序,输出会是:
⚠️ 你来自高风险地区,请进行核酸检测并报备!
⚠️ 你的健康码不是绿码,暂时无法进入公共场所!
因为这个例子里你虽然不是阳性,但你来自高风险地区而且健康码也不是绿的,这两个条件都分别成立了,程序都会逐一进行判断并执行。
6.3.2 “杠精”为什么这里用 and 不合适?
当然,你可能会说,上面的疫情监测程序我们也可以用逻辑运算符 and
啊,比如:
# 使用 and 的例子(条件必须同时满足)
if is_positive and from_high_risk_area:
print("⚠️ 高风险地区阳性患者,请立即特殊隔离!")
这里当然可以用 and
,不过我这个例子主要是帮助你理解什么时候适合用多个独立的 if
,千万别杠精哦~
你以为这就结束了?不对,你要敏锐一点,要察觉到一些使用 and 不合适的情况。多多看看上面的程序,看看能不能有什么感受或者疑惑。思考一下,别着急往下阅读。
在上面我举的疫情检测例子中:
- 判断是否阳性
- 判断是否来自高风险地区
- 判断健康码是否是绿码
这几个条件其实是独立的,不是非要同时满足。比如:
- 只要阳性就一定得隔离,不管你是不是来自高风险地区;
- 只要健康码不是绿码,就不能进入公共场所,不管你是不是阳性;
- 只要来自高风险地区,就需要核酸检测并报备,不管你健康码是不是绿的。
如果你使用了 and
:
if is_positive and from_high_risk_area:
print("⚠️ 高风险地区阳性患者,请立即特殊隔离!")
这个判断的含义就成了“同时满足两个条件才执行”,如果你只是阳性但不是高风险地区,或者你只是高风险地区但并不是阳性,那么这条判断就不会执行,这显然漏掉了重要的情况。在疫情期间,这样是及其危险且对他人生命健康极其不负责的情况。
所以,这个情景下是不可能,也是不能使用 and 的。你写的程序未来有可能会提供给万万人使用,希望你写的程序是富有责任心的,也是安全的。
尤其在疫情这种特殊背景下,这种判断遗漏是极其危险的,也是对他人生命健康极不负责的表现。因此,在这种场景下绝不应该使用 and
来进行条件判断。
请记住,你今天写下的程序,未来可能会影响千千万万的人。希望你编写的每一行代码都是安全、谨慎、并且富有责任心的。不论是否会影响,我们始终要坚守的原则就是:对每一行代码负责,对每一个使用者负责。让代码严谨、安全,充满敬畏与责任心。
我在 2022-05-20 10:35:00 是,在《写 while 循环专项练习》时写下:程序员就是连接人与机器之间的桥梁,如同马路上的路、桥不能出问题,我们用代码制造的“桥梁”也是如此!
最后的最后,我再给你几个使用多个独立 if 的代码例子,拿走不谢哈哈哈哈哈。
示例1:检查一个数字的多个属性
number = 12
if number % 2 == 0:
print("是偶数")
if number % 3 == 0:
print("能被3整除")
if number > 10:
print("大于10")
输出:
是偶数
能被3整除
大于10
解释: 这些判断条件是相互独立的,一个数可以同时满足多个条件,所以我们用多个 if
。
示例2:检查一个数字的多个属性
age = 20
if age >= 18:
print("成年人")
if age >= 16:
print("可以申请驾照")
if age >= 14:
print("可以申请身份证")
输出结果为:
成年人
可以申请驾照
可以申请身份证
至于什么时候用 and 本节后面还会再提一次,这里我稍微提一下。
当多个条件必须同时满足,缺一不可时才适合用 and
。比如:判断“用户同时输入了用户名 且 密码都正确”时,使用 and
就非常合适。
username = "admin"
password = "123456"
if username == "admin" and password == "123456":
print("登录成功!")
else:
print("用户名或密码错误!")
6.3.3 什么时候使用 if...elif...else
当多个条件之间是互斥的(只能满足其中一个),或者你希望只执行其中一个分支时,就使用 if...elif...else
结构。这能提高效率,并避免多个分支同时执行带来的逻辑错误。
例如:
- 给定的条件是一系列范围或等级划分,互不重叠,只可能符合其中之一。
- 当条件之间有严格的优先顺序时。
比如你去电影院看电影,买票的时候售票员会按照你的年龄决定票价:
- 5岁以下的小孩 免费;
- 5到18岁 半价;
- 18到60岁是正常的 全价;
- 60岁以上的老人 免费。
很明显,这些条件互相之间是互斥的,也就是说你只可能落入其中一个分类,而不可能同时属于两个或多个分类。
我们用代码来表示一下:
age = 70
if age < 5:
print("小朋友,你可以免费观影哦~🎬")
elif age <= 18:
print("青少年半价票,请支付25元!")
elif age <= 60:
print("全价票,请支付50元!")
else:
print("老人家,您可以免费观影哦~🎬")
运行结果:
老人家,您可以免费观影哦~🎬
上面买票这种场景,年龄条件是连续的、不重叠的,只会满足其中的一种情况。程序从第一个条件开始逐一检查,一旦符合某一个条件,程序便立即停止后续的判断,这样不仅高效,而且符合实际生活中的逻辑需求。
6.3.4 在这个例子中,用 or
是否合适?
这时,老样子。你是不是还是会觉得这种情况我总能使用 or 了吧。我们先尝试一下用 or
把上面的电影票程序写出来,看看效果如何:
age = 70
if age < 5 or age > 60:
print("免费观影哦~🎬")
elif age >= 5 and age <= 18:
print("青少年半价票,请支付25元!")
elif age > 18 and age <= 60:
print("全价票,请支付50元!")
这样写出来,表面看起来好像也没问题。但实际上,这种用法会带来一些隐患:
- 可读性变差了:
or
一旦多了,代码可读性就会降低,不容易一眼看出程序的判断逻辑。 - 更容易出错:随着条件变得复杂,你会越来越难维护。
- 不够清晰:当你增加更多的条件范围或修改判断标准时,用
or
会显得特别繁琐。
我们再看看原来用 if...elif...else
写的版本:
age = 70
if age < 5:
print("小朋友免费观影哦~🎬")
elif age <= 18:
print("青少年半价票,请支付25元!")
elif age <= 60:
print("全价票,请支付50元!")
else:
print("老人家免费观影哦~🎬")
清晰明确:年龄范围明确区分。
易于维护:你以后修改条件时,只需要调整对应的范围即可。
代码安全可靠:程序更直观,不容易出现漏掉条件的情况。
对于 or 的使用,后面会讲解什么时候适合 or,以及什么时候适合 and。不过我这里稍微先,提供一个 or 的代码示例。当你想把多个相对独立的条件合并为同一个判断时,使用 or
很合适。例如:
# 用户输入 y 或 Y 表示确认
answer = input("确认退出吗?(y/n)")
if answer == 'y' or answer == 'Y':
print("已退出程序。")
就类似你同时看上了多个男的,但是你只能和其中一个男的的谈恋爱。
再回到一开始的根据分数判断等级的代码:
score = 75
if score >= 90:
print("优秀")
elif score >= 80:
print("良好")
elif score >= 60:
print("及格")
else:
print("不及格")
输出:
及格
解释: 分数等级是互斥的,一个分数只能对应一个等级,所以使用 if...elif...else
更合适。
6.3.5 总结一下
下面是一份最终的总结表,把我们前面讨论过的多种情形及对应的用法一一罗列出来,方便你在不同场景下快速对照和选择合适的语句结构。
场景 | 条件关系 | 示例/举例 | 推荐写法 | 原因和特点 |
---|---|---|---|---|
多个独立的 if | 条件之间不互斥,可能多个同时满足 | 1. 疫情管理:是否阳性、是否来自高风险区、健康码是否绿码等 2. 检查数字是否能被 2 整除、3 整除、5 整除 | 多个平行的 if 语句 | 1. 每个条件都会单独判断,并且都可能执行 2. 能同时对多个独立条件采取行动 3. 注意:若不想多次执行,需要用 if...elif |
if...elif...else | 条件之间互斥,只需满足其中一个 | 1. 给分数分等级:优秀、良好、及格、不及格 2. 电影院票价:不同年龄段不同票价 | if + 若干 elif + else | 1. 程序自上而下按顺序判断,一旦满足其中一个条件就终止判断 2. 各分支对应互斥的情况(只能满足其中之一) 3. 代码简洁、逻辑清晰,避免多次输出 |
使用 and | 多个条件必须全部同时成立才执行 | 1. 用户名和密码必须都正确 2. 物品重量超标并且体积超标 | 在单个 if 中用 and 连接条件 | 1. and 表示“并且”,任何条件不成立时都不执行 2. 适用于所有条件都需要满足的情况 |
使用 or | 只要任意一个条件成立就执行 | 1. 用户输入 y 或 Y 表示确认 2. 数字是负数或 0 时需特殊处理 | 在单个 if 中用 or 连接条件 | 1. or 表示“或者”,只要有一个条件为真就执行 2. 适用于任意条件成立都需要执行的情况 |
🔖 如何选择?一句话总结:
- 想要所有满足条件的代码块都被执行 ⇒ 多个独立的
if
; - 只想执行第一个满足条件的代码块 ⇒
if...elif...else
; - 条件必须同时满足 ⇒
and
; - 任意一个条件满足就行 ⇒
or
7. 什么时候适合用 and
和 or
其实前面探究多个独立 if 和 if…elif…else… 已经提到和总结,虽然用重复论述之嫌,但我还是在此再次强调一下。并且融合在前面的讲解,在未来你想快速查找时不方便,这里独立出来再讲一遍,也是为了方便未来查询。
7.1 多个条件同时成立时
如果程序里需要满足多个条件同时成立才能执行时,就使用 and
。
生活中的例子,银行取款时。必须同时满足:
输入的密码正确;
卡里余额足够。
只有当这两个条件都成立时,银行才允许取款。用代码来举例说明:
password_correct = True
balance = 500
withdraw = 300
if password_correct and balance >= withdraw:
print("✅ 取款成功!")
else:
print("❌ 取款失败,余额不足或密码错误!")
7.2 只需要任一条件成立时
如果多个条件里,只要满足其中任何一个就可以执行,就使用 or
。
生活中的例子:比如某景区搞优惠活动,只要满足以下任一条件都能享受免费门票:
- 身高不足 1.2 米的儿童;
- 年龄超过 65 岁的老人;
- 持有军人证件。
用代码来举例说明:
height = 1.5 # 身高1.5米
age = 70 # 年龄70岁
has_military_id = False # 没有军人证
if height < 1.2 or age > 65 or has_military_id:
print("🎫 您可以免费进入景区!")
else:
print("💰 您需要购票进入景区。")
在这个例子里,年龄超过了65岁,因此符合免费条件,只要满足其中一个就能免费。
7.3 总结一下
情况 | 使用方法 | 举例 |
---|---|---|
所有条件必须同时满足 | and | 密码正确 且 余额足够才允许取款 |
多个条件满足任意一个即可 | or | 身高不足、年龄较大 或 有证件任何一个条件即可免费 |
8. 注意:判断使用双等号 ==
要比较两个值是否相等,必须使用 ==
。如果不小心写成了单等号 =
,就变成了赋值语句,这会导致逻辑错误甚至报错。请务必留意自己在写条件判断时用的是双等号。
9. 改进性别判断程序
9.1 使用字符串内置函数
回到一开始的性别判断程序:
user_gender = input("请输入您的性别(F/M):")
if user_gender == "F":
print("你是萌妹子")
elif user_gender == "M":
print("你是糙汉子")
else:
print("输入不正确,请输入 F 或 M")
上面的程序,只能允许用户输入大写的 F 或 M 才能正常匹配。我们来测试看看:
# 测试一:
请输入您的性别(F/M):f
输入不正确,请输入 F 或 M
# 测试二:
请输入您的性别(F/M):m
输入不正确,请输入 F 或 M
但实际使用中,往往需要支持:在用户输入大写或小写 F、f、M、m 时都需要能正常匹配。该如何改进呢?好好思考一下,并尝试编写代码。
既然要支持用户输入大小写都支持,从另一个方面理解则是:如何使我们的程序,不区分大小写。
既然是这样的情况,我们想想有什么方法“统一用户输入”,用户输入我们使用的是 input()
函数,并且 input()
函数得到的都是字符串。就可以使用字符串的 .upper()
来统一输入得到的字符串转成大写或者使用 .lower()
统一输入得到的字符串转成小写。
代码实现如下,使用 .upper()
函数实现:
user_gender = input("请输入您的性别(F/M):").upper()
if user_gender == "F":
print("你是萌妹子")
elif user_gender == "M":
print("你是糙汉子")
else:
print("输入不正确,请输入 F/f 或 M/m")
使用 .lower()
实现:
user_gender = input("请输入您的性别(F/M):").lower()
if user_gender == "f":
print("你是萌妹子")
elif user_gender == "m":
print("你是糙汉子")
else:
print("输入不正确,请输入 F/f 或 M/m")
上面成功解决问题,那么我们能不能不使用字符串的内置函数:.upper()
或 .lower()
来实现呢?
9.2 不使用字符串内置函数可以实现吗?
9.2.1 存在的问题
我们来分析一下:不论用户输入的是大写 F,还是小写 f。这两个条件是不需要同时成立的,只需要能符合其中之一就行。那你有没有想到什么?(从“其中之一”这个词,有没有联想到什么?)
那我们就可以使用 or 来实现,但是有学生写成下面的代码,你觉得对吗?
user_gender = input("请输入您的性别(F/M):")
if user_gender == "F" or 'f':
print("你是萌妹子")
elif user_gender == "M" or 'm':
print("你是糙汉子")
else:
print("输入不正确,请输入 F/f 或 M/m")
不对,上面的代码有问题。什么问题呢?我们先来测试运行一下:
# 测试一:
请输入您的性别(F/M):F
你是萌妹子
# 测试二:
请输入您的性别(F/M):f
你是萌妹子
# 测试三:
请输入您的性别(F/M):M
你是萌妹子
# 测试四:
请输入您的性别(F/M):m
你是萌妹子
# 测试五:
请输入您的性别(F/M):what?
你是萌妹子
不论我们输入什么,得到的结果都是:“你是萌妹子“,What?什么情况?我们来分析一下,一起探究是什么问题。
9.2.2 分析问题
我们来看这一行代码,是下面这行代码出现了问题:
if user_gender == "F" or 'f':
这里的本意是希望用户输入为大写 “F” 或小写 “f” 时,都满足条件。但实际上,这里的语法出了问题,Python 执行的逻辑却并非如此。
条件判断语句的正确写法是:
if 条件1 or 条件2:
在上面的代码中:
if user_gender == "F" or 'f':
实际上被 Python 解释为:
if (user_gender == "F") or ('f'):
这里的 user_gender == "F"
是一个条件判断表达式,结果为 True 或 False。然而后面的 'f'
本身是一个非空字符串,在 Python 中非空字符串会被视为 True。
因此,上面表达式中:
- 当输入为
"F"
时,第一个条件满足,执行 print。 - 当输入为其他字符时,第一个条件不满足,但后面条件是非空字符串
'f'
,恒为 True,因此整体表达式也始终为 True。(注意:只有空字符串(''
)才是False
。)
这也解释了为什么无论输入什么,都会输出“你是萌妹子”。
类似的问题也出现在:
elif user_gender == "M" or 'm':
这里同样,字符串 'm'
永远为真,意味着这行代码实际根本不会执行(因为前面的 if
语句已经覆盖了所有输入情况)。
9.2.3 正确写法
正确的写法应该是: 将每个判断单独写完整,如:
user_gender = input("请输入您的性别(F/M):")
if user_gender == "F" or user_gender == "f":
print("你是萌妹子")
elif user_gender == "M" or user_gender == "m":
print("你是糙汉子")
else:
print("输入不正确,请输入 F/f 或 M/m")
现在再测试一下:
# 测试一:
请输入您的性别(F/M):F
你是萌妹子
# 测试二:
请输入您的性别(F/M):f
你是萌妹子
# 测试三:
请输入您的性别(F/M):M
你是糙汉子
# 测试四:
请输入您的性别(F/M):m
你是糙汉子
# 测试五:
请输入您的性别(F/M):what?
输入不正确,请输入 F/f 或 M/m
此时的程序符合我们的需求。
9.2.4 延伸思考与小结
- 条件判断中,不能简单地把一个变量与多个值用 or 连在一起,如
if a == "x" or "y"
,这是错误的用法。 - 这种情况下正确的用法是单独对每个条件都写完整,如
if a == "x" or a == "y"
。 - 更推荐的方式是在输入时使用统一大小写方式(例如
.upper()
或.lower()
),再做判断,能让代码更加简洁易读。
10. 多重 if 语句
在实际编程中,有时需要在一个判断内部嵌套另一个判断,这时就用到了多重 if
语句。下面是一个示例:
有时我们需要在一个条件满足的情况下,再细分出其他条件。可以在 if
块内部嵌套另一个 if
块,这种结构称为多重 if(又叫嵌套 if)。
user_gender = input("请输入您的性别 (F/M): ")
user_is_student = input("您是学生吗? (Y/N): ")
if user_gender == 'F':
if user_is_student == 'Y':
print("你是萌妹子学生")
elif user_is_student == 'N':
print("你是萌妹子")
else:
print("输入不正确")
elif user_gender == 'M':
print("你是糙汉子")
else:
print("输入不正确,请输入 F 或 M")
注意:不同层级的条件判断互不影响
解析:
- 外层
if
判断用户性别,如果user_gender == 'F'
,就继续判断user_is_student
的值; - 内层
if
进一步判断是否为学生,如果user_gender == 'M'
,直接打印 “你是糙汉子”; - 如果以上情况都不满足,则执行最外层的
else
。
注意:不同层级的条件判断各自独立,只有当外层条件满足时才会进入内层判断。多重 if
虽然可以实现更加复杂的逻辑,但也会导致程序阅读难度上升,编写时需要小心层级关系。
11. 占位语句 pass
pass
关键字可以理解为“占位语句”,当编写程序时有些地方暂时还不知道要放什么代码,或者还没实现具体逻辑,需要先让代码结构完整、能够运行时,就可以使用 pass
来填充空白位置。这样做就像在写文章时,你脑子里已经有了大致结构,比如决定了要分章节,但有些章节内容还没想好要写什么,就先写上一个简单的占位符“(此处待写)”,保证文章脉络先完整,之后再回头补充具体内容。
11.1 为什么需要 pass
?
在 Python 中,如果你只写了个空的函数、循环或条件语句,而什么都不做就会报错。换言之,Python 期望你给它一个“能执行”的东西,如果不想真正执行任何操作,又需要保证结构存在,这时候 pass
就可以派上用场。
11.1.1 现实生活类比
想象一下你在做一份个人待办清单,你打算先把每天要做的主要事情分门别类列出来:
- 早上:——
- 中午:——
- 晚上:——
你只是先把框架列好,等到具体时间再回过头去填写,这样你的日程就不会缺少这些时间段。同理,在编程里,我们希望先写好程序结构,比如“如果发生某事就执行XXX”,但是还不知道该怎么实现“XXX”时,就用 pass
表示“我知道这里将来需要有一些操作,但现在先留一个空”。
11.1.2 pass
的常见使用场景
函数尚未实现:先定义好函数名和参数,使用
pass
让代码能正常运行,等后续知道如何实现时再补充。def future_function(): pass # 占位,表示日后这里会实现具体功能
类中方法占位:类的部分方法需要先“声明”出来,后面再去编写实现逻辑。
class MyClass: def method_one(self): pass # 先空着,未来再做实现 def method_two(self): print("This method is complete.")
分支结构中先留空:当你写了一个分支条件,但里头还没想好要干嘛,可以先用
pass
占位。x = 10 if x > 5: pass # 之后再写具体操作 else: print("x <= 5, 直接做某些处理")
循环中暂时不处理任何事:在循环里如果你还没想好要处理什么,想先把循环结构敲定,也可以用
pass
。for i in range(5): pass # 循环内暂时无任何操作
11.2 从零开始,一步步演示
11.2.1 例子 1
假设你正在开发一个简单的猜数字游戏。你先搭建好框架,包括一个主循环和一些功能函数,但具体的逻辑实现还没想好,你打算先让程序能“跑起来”。这时,你的代码雏形可能如下:
def game_start():
pass # 这里将来要加游戏的初始化操作,比如欢迎界面
def check_guess(number, guess):
pass # 将来要实现判断逻辑,告诉玩家他们猜得对不对
def run_game():
# 在这里我们先写一个结构,让程序能跑起来
# 但是因为具体逻辑还没有,所以用 pass 占位
for i in range(3): # 比如我们想让玩家最多猜3次
pass
print("游戏结束")
# 先调用游戏主函数
game_start()
run_game()
虽然这段代码目前什么都没做,但是却可以确保结构上是完整的,能够顺利运行而不出错。等到你后面决定好每个函数要干什么,再把 pass
替换成真正的实现代码就行了。
11.2.2 例子 2
假设我们打算写一个简单的函数,用来判断某个数字是正数、负数,还是零,并按照不同分支做出对应处理。但在最初,我们可能还没想好具体要怎么处理,只想先把代码的整体结构搭建好。在这种情况下,就可以使用 pass
来占位。
- 第一步:先搭框架
def check_number(num):
if num > 0:
pass # 这里将来要加上当 num > 0 时的处理逻辑
elif num < 0:
pass # 这里将来要加上当 num < 0 时的处理逻辑
else:
pass # 这里将来要加上当 num == 0 时的处理逻辑
# 测试一下
check_number(10) # 目前不会输出任何内容
运行上面的代码,你会发现什么都没发生,但也不会报错。这是因为 pass
起到了“空白语句”的作用,让 Python 知道“此处将来还会有东西”,从而继续往下运行程序。
现实生活类比
想象一下,你打算制定一套规则,比如“上班迟到就怎样,上班早退又怎样,按时到岗又怎样”。你还没真正想好对这三种情况采取什么具体措施,但你至少先把这三种分支列出来,以便日后再逐条补充管理规定。这跟我们在 if-elif-else
语句里用 pass
先占位,再后来补充逻辑是一个道理。
- 第二步:逐步完善具体逻辑
等到你想好了每个分支要做什么时,就可以把对应的 pass
替换成真正的实现。比如:
def check_number(num):
if num > 0:
print(f"{num} 是正数,建议我们做些正数特有的处理。")
elif num < 0:
print(f"{num} 是负数,或许需要警示或特殊处理。")
else:
print("这是零,可以视具体需求而定是否处理。")
# 再次测试
check_number(10) # 输出:10 是正数,建议我们做些正数特有的处理。
check_number(-5) # 输出:-5 是负数,或许需要警示或特殊处理。
check_number(0) # 输出:这是零,可以视具体需求而定是否处理。
这样一来,代码从最开始的“框架阶段”过渡到“功能完善阶段”,整个开发过程都显得有条不紊。
11.3 总结
- 核心概念:
pass
只是一个占位符,让你可以先写下程序结构而不需要马上实现所有细节。 - 使用目的: 保持代码的语法完整,程序可以正常运行,不至于报“空语句”错误。
- 应用场景: 空函数、空类方法、占位的条件分支、以及暂未实现逻辑的循环结构等。
当你遇到“我知道这里将来一定会有内容,但现在先空着”这种场景,就可以大胆地使用 pass
。就像给自己留了一个提示,日后你一看就知道:哦,原来这里还有事情要处理。并且还可以等我们哪天灵光一现,需要加上完整逻辑时,再把 pass
换成实际操作即可。这样既能保证程序骨架清晰,又能在开发流程中分阶段实现功能。
适当的使用 pass 不仅仅能让我们在编程中先掌控整体脉络,再陆续填入细节,就好比先把房子的框架搭起来,再慢慢装修,不会因为一时没想好家具布局而停工。
当然,在团队合作当中也是经常使用。比如你作为团队的核心大脑,决定团队中每个人的分工和任务。你可以为每个人的任务编写代码框架,并使用 pass 占位。然后分发下去,这样团队成员看见 pass 时就知道,这是等待编写的任务代码。
11. if 小试牛刀:实战案例
11.1 判断用户输入的数据是奇数还是偶数
11.1.1 初始版本以及存在的问题
编写一个程序,判断用户输入的数据是奇数还是偶数。这个问题的核心点在于:如何判断用户输入的数据是奇数还是偶数。这个时候,我们联系现实:在数学中,你会如何判断数字是奇数还是偶数?——是不是 2 的倍数。
那么既然要判断是不是 2 的倍数,用什么运算符呢?那我们得看看是不是 2 的倍数会有什么特点?是 2 的倍数除的尽,不是 2 的倍数除不尽。
很好,核心逻辑解决了。还有一个小问题:input()
得到的是什么类型?——字符串。我们要去计算,Python 当中不同的数据类型不能运算,那么我们应该如何呢?——使用 int 进行强制转换即可!
代码实现如下:
# 获取用户输入
number = int(input("请输入一个整数: "))
# 使用模运算符来判断奇数还是偶数
if number % 2 == 0:
print(f"{number} 是偶数。")
else:
print(f"{number} 是奇数。")
上面的代码初步实现,但是我想一步步带你发现问题和优化。上面代码不够强壮,在用户输入的不是纯数字字符串时会报错。
请输入一个整数: a
Traceback (most recent call last):
File "/Users/huangjiabao/bornforthis.cn/demo.py", line 2, in <module>
number = int(input("请输入一个整数: "))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'a'
我们如何优化代码呢,让代码更强壮呢。要优化,则要找到问题存在的地方。哪一行代码导致报错?从报错可知,在代码第一行时 int()
转换非数字时,报错了。字符串 a
有对应的数字吗?没有,所以报错。
找到问题了,咱们就开始解决。怎么解决呢?先看看我给你的例子:我们生活中去商场,人家销售不会不分男女随意推销,甚至不适合性别的商品。销售是会看是男的,则推销男的商品和男的会送的礼物等。如果是女的,则会推销女的适合的商品。
11.1.2 第一次优化(去掉冗余判断)
在代码中也是一样的,我们在字符串转换数字之前,先判断一下:用户输入的是不是纯数字字符串,不是就不转换。代码实现如下:
# 获取用户输入
number = input("请输入一个整数: ")
# 使用模运算符来判断奇数还是偶数
if number.isdigit() == True:
number = int(number)
if number % 2 == 0:
print(f"{number} 是偶数。")
else:
print(f"{number} 是奇数。")
elif number.isdigit() == False:
print("不是纯数字")
上面代码中,使用到了 if number.isdigit() == True
这个语法实际上可以改写成 if True
的形式。为什么呢?因为 number.isdigit()
本身返回的就是 True
或 False
,因此不需要再显式写成 number.isdigit() == True
或 number.isdigit() == False
。
去掉冗余判断 == True
和 == False
,代码优化如下:
# 获取用户输入
number = input("请输入一个整数: ")
# 使用模运算符来判断奇数还是偶数
if number.isdigit():
number = int(number)
if number % 2 == 0:
print(f"{number} 是偶数。")
else:
print(f"{number} 是奇数。")
else:
print("不是纯数字")
11.1.3 第二次优化(减少嵌套,提高可读性)
但是还可以继续优化简洁一些。嵌套会是程序逻辑变得复杂,不是嵌套不能用,我只是刻意的要带你练习一下 not 的用法。你可以先停止阅读,自行尝试编写之后再继续阅读。
# 获取用户输入
number = input("请输入一个整数: ")
# 使用模运算符来判断奇数还是偶数
if not number.isdigit():
print("不是纯数字")
elif int(number) % 2 == 0:
print(f"{number} 是偶数。")
else:
print(f"{number} 是奇数。")
为什么要这么写?
使用
not number.isdigit()
提前拦截非数字情况,先排除不符合条件的输入,程序逻辑变得更清晰。使用
elif
而非新的嵌套if
,逻辑上更加简单、明确。为什么这样可以实现,核心依赖是什么?
- 依赖一:not 的转换特性;(你可以理解成黑白颠倒)
- 依赖二:if…elif…elif…else…只会执行其中一个;
上面的程序,我一步步带你实现和优化后。我不仅仅想让你会写这个代码和理解,更重要的是想让你知道:在实际开发写程序时,不要一开始就想写到最好,所有不是一蹴而就的。是需要一点点开发然后逐步改进优化,所以在未来你写代码时要记住一个原则: 先实现功能,再去优化,否则一切会很乱。 我写于 2022年6月2日,在此跟你分享。
这也是为什么很多软件,比如像微信功能挤牙膏一样,很长时间挤一点。除了商业计划之外,另外一个就是这是个大工程,需要一步步实现。总不能从一行代码都没有,一步就开发成现在的微信吧。
说点额外却很重要的:成长需要时间,不仅仅时技术,人也需要时间。慢慢来,慢下来。凡是自然界中的好东西,都是缓慢的。就像太阳一点点升起、花一朵朵开、粮食成熟、细水长流,这些东西都是慢慢来的。相反,那些骤然的都是灾难。孔夫子说:欲速则不达。所以别太着急,我觉得慢慢是个很好的词。慢慢成长,慢慢遇见,慢慢看世间沉浮,慢慢看岁月静好。
后续的题目比较简单,我会直接提供答案。自行思考和编写~
11.2 最大数判断
编写一个程序,接收三个整数作为输入,并输出其中的最大值。
a = int(input("输入第一个整数: "))
b = int(input("输入第二个整数: "))
c = int(input("输入第三个整数: "))
if a >= b and a >= c:
print(f"最大的数是 {a}")
elif b >= a and b >= c:
print(f"最大的数是 {b}")
else:
print(f"最大的数是 {c}")
11.3 登录验证
设计一个程序,要求用户输入用户名和密码。如果用户名是 admin
且密码是 123456
,则打印“登录成功”,否则打印“用户名或密码错误”。
username = input("请输入用户名: ")
password = input("请输入密码: ")
if username == "admin" and password == "123456":
print("登录成功")
else:
print("用户名或密码错误")
11.4 基础条件判断:判断特定数
写一个 if
语句,如果 a
大于 b
,则打印 "a is greater than b"
。
a = 10
b = 6
if a > b:
print("a is greater than b")
11.5 分数等级判定
编写一个程序,根据用户输入的分数(0-100),输出他们的等级。等级判定标准如下:
- 分数大于等于 90:输出:"A"
- 分数在 80 到 89 之间:输出:"B"
- 分数在 70 到 79 之间:输出:"C"
- 分数在 60 到 69 之间:输出:"D"
- 分数小于 60:输出:"F"
# 获取用户输入的分数
score = int(input("请输入你的分数(0-100):"))
# 首先确保输入的分数在0到100之间
if 0 <= score <= 100:
# 分数大于等于90
if score >= 90:
print("A")
# 分数在80到89之间
elif score >= 80:
print("B")
# 分数在70到79之间
elif score >= 70:
print("C")
# 分数在60到69之间
elif score >= 60:
print("D")
# 分数小于60
else:
print("F")
else:
print("输入的分数不在有效范围(0-100)内,请重新输入!")
11.6 奇偶数分级
编写一个程序,根据用户输入的整数,首先判断这个数字是正数、负数还是零。然后,进一步判断该数字是奇数还是偶数(仅当数字为正数或负数时)。输出应该是这样的形式:"正奇数", "负偶数" 等。
# 获取用户输入的整数
number = int(input("请输入一个整数:"))
# 判断数字是正数、负数还是零
if number > 0:
# 正数
if number % 2 == 0:
print("正偶数")
else:
print("正奇数")
elif number < 0:
# 负数
if number % 2 == 0:
print("负偶数")
else:
print("负奇数")
else:
# 零
print("零")
11.7 年份分类
编写一个程序,根据用户输入的年份,判断该年份是平年还是闰年。闰年的条件如下:如果年份能被 4 整除但不能被 100 整除,或者能被 400 整除,则是闰年。
如果是闰年,程序还需要进一步判断该年份是不是一个世纪年(即是否能被 100 整除)。输出应包括年份是平年、闰年还是世纪闰年。
# 获取用户输入的年份
year = int(input("请输入一个年份:"))
# 判断是否是闰年
if (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0):
# 检查是否是世纪年
if year % 100 == 0:
print(f"{year}是世纪闰年")
else:
print(f"{year}是闰年")
else:
print(f"{year}是平年")
更新日志
92f62
-于60621
-于ac55a
-于f6981
-于1be89
-于87164
-于1c35a
-于01ad5
-于d8167
-于ddfcf
-于3c1f2
-于821ac
-于18871
-于f4510
-于7cc7f
-于5c589
-于88ecd
-于a491a
-于68704
-于cfd6c
-于fd9bf
-于5eee9
-于3b0a5
-于aa09d
-于5913b
-于90c48
-于90932
-于63bb6
-于eff78
-于8cb25
-于d632d
-于280d7
-于360c8
-于e8841
-于491ee
-于88347
-于e5efb
-于8a8dc
-于dd0ba
-于b6faa
-于4db1d
-于9c69b
-于aa22c
-于c85f4
-于e3156
-于2fcf3
-于8ca77
-于935dd
-于cc2ed
-于fabda
-于7d4b2
-于adde8
-于d2f64
-于cbb3a
-于610fe
-于f08aa
-于76989
-于86c50
-于027da
-于