User:Xyy23330121/Python/布尔值与 if 语句

来自维基学院


布尔值是程序表达判断结果的方式。总共有两种布尔值 TrueFalse ,分别代表“真(正确)”和“假(错误)”。布尔值在以下的内容中起到重要作用。

if 语句[编辑 | 编辑源代码]

在编写程序时,有时会出现需要按情况执行代码的时候。此时,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 语句的子句。

对于 ifelse 等语句而言,其后必须要跟着子句。当子句只需要一行时,可以不另起一行。以下的方法也是可行的:

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 == 1a <= 2 的表达式。本章将详细讲解这些表达式的意义。

以下表格列举了比较运算的一些运算符:

运算符 含义
< 小于
<= 小于或等于
> 大于
>= 大于或等于
== 等于
!= 不等于

在 Python 中,比如 1 + 2 会输出 3 ,许多表达式是向外输出一个结果的。比较运算的表达式向外输出的是布尔类型的布尔值。

比如以下代码:

print(1 > 2)

1 > 2与事实不符,因此1 > 2的表达式会返回False,从而代码会输出:

False

与其它语言不同,python支持比较运算符的任意串联,比如x < y <= z只有在x < yy <= z时才会返回True

一般来讲,只有同为数字,才能进行小于、小于等于、大于、大于等于的比较。对于特殊情况,请参见之后的类的方法与数学运算章节,现在不需要读者掌握此内容。

math.isclose[编辑 | 编辑源代码]

浮点数误差可以十分显著——显著到比较运算符会返回错误的结果。我们看以下示例:

print(0.1 + 0.2 == 0.3) #输出:False

为此,math 模块提供了 math.isclose 函数来解决一部分误差问题。

math.isclose(a, b, *, rel_tol=1e-9, abs_tol=0.0)

当两个数字 ab 足够接近时,返回 True。否则返回 False

“足够接近”是由相对容差 rel_tol 和绝对容差 abs_tol 决定的,具体来讲,只要 ab 的差小于以下两者中的一个,就认为足够接近:

  1. ab 中绝对值较大的那个、其绝对值 max(abs(a), abs(b)) 和相对容差的乘积。
  2. 绝对容差。

绝对容差对两者都接近零的情况时很有用:对于默认情况,如果比较 1e-111e-12。两者的差为 9e-12 已经很小,但依旧大于 1e-11 * 1e-9,并导致该函数返回 False。读者应当综合各种情况正确设置容差。

布尔运算[编辑 | 编辑源代码]

并非只有比较运算会输出布尔值,布尔运算也会输出布尔值。以下是三种布尔运算符:

运算符 含义 解释
and a and b只有当ab都为True时才会输出True,否则输出False
or a or b只要ab两者之一为True时就会输出True。只有两者都为False,才会输出False
not not aaTrue时输出False,当aFalse时输出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 语句,我们称这样的结构是一种嵌套。以下是一个例子:

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。

elif[编辑 | 编辑源代码]

为简便起见,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 "错误时的输出")  #输出:错误时的输出

当条件表达式中,ifelse之间的部分返回True时,条件表达式会输出if左边的内容。反之,会输出else右边的内容。条件表达式的运算顺序高于且仅高于赋值的=+=:=等以及用于匿名函数的lambda表达式,所以基本不需要添加括号。

lambda表达式将在之后的章节学习。读者此时并不需要掌握这些内容。