User:Xyy23330121/Python/布尔值与 if 语句
布尔值是程序表达判断结果的方式。总共有两种布尔值 True
和 False
,分别代表“真(正确)”和“假(错误)”。布尔值在以下的内容中起到重要作用。
在编写程序时,有时会出现需要按情况执行代码的时候。此时,if 语句很有帮助。我们先看以下示例:
a = 1
if a == 1:
print("注意")
print("a 的值为1")
else:
print("a 的值不为1")
这里,通过进行 if 语句,我们可以按情况执行代码。读者可以尝试把开头的 a = 1
改写为 a = 2
或让它等于其它内容,看看结果。
以上例子中,以下的代码构成了一个“语句组”。
if a == 1:
print("注意")
print("a 的值为1")
其中,两个 print
函数构成了 if
语句的子句。
对于 if
、else
等语句而言,其后必须要跟着子句。当子句只需要一行时,可以不另起一行。以下的方法也是可行的:
if a == 1: print("注意\na 的值为1")
if 语句确认if
后紧跟着的表达式的结果,如果该结果为True
,则执行if
子句,如果该结果为False
,则确认是否有else
语句。如果有else
语句,则执行else
子句。
由上面的讨论,if
后紧跟着的表达式必须是一个会返回布尔值的表达式。接下来介绍几种返回布尔值的表达式。
if
语句的子句也是 if
语句时,如果不换行,会引发语法错误。这是因为:
if a > 1: if a < 2: print(a)
else: pass
此时,Python 无法确定该 else
语句是属于哪个 if
语句的。
Python 通过缩进来确定语句是否是之前语句的子句。缩进就是语句前的空格或 TAB。这里的两个 print
函数前面都是4个空格,所以后面的 print
函数不是前面 print
函数的子句——而是和前面函数同级的语句。而 if
前面没有缩进:缩进少于两个 print
函数前的缩进,从而这两个 print
函数都是 if
子句。
如果不分情况乱打空格或 TAB,或者将 TAB 和四个空格混用,就会出现“缩进错误”。比如:
a = 1
b = 2
会输出以下结果:
IndentationError: unexpected indent
这是由于前面的 a = 1
语句并不支持自己有子句导致的。
上面的示例中,我们使用了 a == 1
或 a <= 2
的表达式。本章将详细讲解这些表达式的意义。
以下表格列举了比较运算的一些运算符:
运算符 | 含义 |
---|---|
< |
小于 |
<= |
小于或等于 |
> |
大于 |
>= |
大于或等于 |
== |
等于 |
!= |
不等于 |
在 Python 中,比如 1 + 2
会输出 3
,许多表达式是向外输出一个结果的。比较运算的表达式向外输出的是布尔类型的布尔值。
比如以下代码:
print(1 > 2)
1 > 2
与事实不符,因此1 > 2
的表达式会返回False
,从而代码会输出:
False
与其它语言不同,python支持比较运算符的任意串联,比如x < y <= z
只有在x < y
且y <= z
时才会返回True
。
一般来讲,只有同为数字,才能进行小于、小于等于、大于、大于等于的比较。对于特殊情况,请参见之后的类的方法与数学运算章节,现在不需要读者掌握此内容。
浮点数误差可以十分显著——显著到比较运算符会返回错误的结果。我们看以下示例:
print(0.1 + 0.2 == 0.3) #输出:False
为此,math 模块提供了 math.isclose
函数来解决一部分误差问题。
math.isclose(a, b, *, rel_tol=1e-9, abs_tol=0.0)
当两个数字 a
和 b
足够接近时,返回 True
。否则返回 False
。
“足够接近”是由相对容差 rel_tol
和绝对容差 abs_tol
决定的,具体来讲,只要 a
和 b
的差小于以下两者中的一个,就认为足够接近:
a
和b
中绝对值较大的那个、其绝对值max(abs(a), abs(b))
和相对容差的乘积。- 绝对容差。
绝对容差对两者都接近零的情况时很有用:对于默认情况,如果比较 1e-11
和 1e-12
。两者的差为 9e-12
已经很小,但依旧大于 1e-11 * 1e-9
,并导致该函数返回 False
。读者应当综合各种情况正确设置容差。
并非只有比较运算会输出布尔值,布尔运算也会输出布尔值。以下是三种布尔运算符:
运算符 | 含义 | 解释 |
---|---|---|
and |
与 | a and b 只有当a 和b 都为True 时才会输出True ,否则输出False
|
or |
或 | a or b 只要a 和b 两者之一为True 时就会输出True 。只有两者都为False ,才会输出False
|
not |
非 | not a 当a 为True 时输出False ,当a 为False 时输出True 。
|
如果我们希望判断一些复杂情况,就需要用到布尔运算。以下示例展示了“当a < 0 或 b > 1时才执行代码”:
if a < 0 or b > 1:
print("a < 0 或 b > 1")
从上面的例子也可以看出,布尔运算符比比较运算符的优先级低。正如1 + 2 * 3
会先计算2 * 3
再计算1 + 6
一样,not True == False
等同于not (True == False)
,因此会输出True
;而True == not False
会引发错误。
在一些情况下,更建议使用比较运算符的串联。利用串联可以让程序少进行一些计算,比如:
1 < 1 + 2 <= 4
在上述计算中,1 + 2
的部分只被计算了一次。而下面的过程
1 < 1 + 2 and 1 + 2 <= 4
中,1 + 2
的部分被计算了两次。如果中间的运算很复杂,用比较运算符的串联可以节省大量时间。
语句组中也可以包含 if 语句,我们称这样的结构是一种嵌套。以下是一个例子:
if a < 1:
if b > 2:
print("a < 1 且 b > 2")
else:
print("a < 1 且 b <= 2")
else:
if a == 2:
print("a >= 1 且 a == 2")
else:
print("a >= 1 且 a != 2")
嵌套子语句组前的缩进,必须比父语句组要更多。为了方便阅读以及防止一些莫名其妙的情况,一个项目的代码要么每一级缩进都增加四个空格,要么每一级缩进都增加一个TAB。
为简便起见,python 将 else 和 if 合为一体。以上的代码也可以写为:
if a < 1:
if b > 2:
print("a < 1 且 b > 2")
else:
print("a < 1 且 b <= 2")
elif a == 2:
print("a >= 1 且 a == 2")
else:
print("a >= 1 且 a != 2")
有一些情况不需要考虑缩进,这里先讲第一种情况:括号。
在 Python 中,在括号未闭合时,可以在逗号等运算符处换行。换行后代码会被当作和换行前的代码在同一行中,因此不必考虑缩进的问题。比如下面两个代码,运行的结果是完全相同的:
print("两数字相加的结果为:", float(input("请输入第 1 个数字:")) + float(input("请输入第 2 个数字:")))
print("两数字相加的结果为:",
float(input("请输入第 1 个数字:"))
+ float(input("请输入第 2 个数字:")))
而对同一行代码,Python 会忽略表达式中的TAB和空格,所以可以随意添加缩进。比如,以下代码和上面两个代码,运行结果也是相同的:
print("两数字相加的结果为:",
float(input("请输入第 1 个数字:"))
+ float(input("请输入第 2 个数字:")))
但是要注意,不能在变量中间换行,比如:
print("两数字相加的结果为:",
float(input("请输入
第 1 个数字:"))
+ float(input("请输入
第 2 个数字:")))
由于字符串中间被视为是断开了,这里会报错。
条件表达式(也被称为:三元运算符)具有类似 if 语句的功能。我们有以下示例:
print("正确时的输出" if 0 < 1 else "错误时的输出") #输出:正确时的输出
print("正确时的输出" if 0 > 1 else "错误时的输出") #输出:错误时的输出
当条件表达式中,if
和else
之间的部分返回True
时,条件表达式会输出if
左边的内容。反之,会输出else
右边的内容。条件表达式的运算顺序高于且仅高于赋值的=
、+=
、:=
等以及用于匿名函数的lambda
表达式,所以基本不需要添加括号。
lambda
表达式将在之后的章节学习。读者此时并不需要掌握这些内容。