Skip to main content

条件语句

条件语句在编程中用于根据一定的条件控制程序的执行流程,它会让程序根据不同的条件执行不同的代码块,是编程中实现决策逻辑的基本方式之一。

代码块

代码缩进是编程中的一个常见概念,指的是某一行代码行的起始部分有一定数量的空白空间,空白后面才是真正的代码。

在多数编程语言中,代码块的界限通常是由特定的符号(比如花括号 {}、小括号 ())或特定的关键字(比如 begin 和 end)定义的。在这些语言里,代码缩进只是为了美观和提高可读性,代码缩进不会影响程序的逻辑。

然而,Python 使用了一种不同的策略:代码块的界限是由缩进定义的。这种设计决策旨在使代码更加可读,并鼓励程序员写出结构清晰、整洁的代码。在同一个代码块中,每一行代码的缩进必须是一致的。这意味着,如果使用了四个空格作为缩进,那么整个代码块中必须都使用四个空格。官方 Python 样式指南(PEP 8)推荐使用 4 个空格作为标准的缩进大小。

我们之前介绍的程序的每一行代码之间,都仅有最简单的顺序逻辑关系,因此每个示例程序都只有一个代码块,还不用考虑缩进的问题。但之后的程序示例将会变得更加复杂,将会包含多个代码块了。

Pythora 星球的居民最开始其实不是特别喜欢 Python 的这种设计。主要是觉得缩进是比较容易搞错的,很容易多几个、少几个空格。毕竟在其它语言中,缩进只影响美观不影响逻辑,因此它没那么重要,容易被忽视。不过,随着时间的推移,大家很快发现,担心是有些多余的,在习惯了 Python 的代码分块方式之后,这种缩进方式并没有导致更多的错误,而且它也确实可以提高代码的整洁度和可维护性。

if else 语句

if-else 结构是编程中最常见的条件结构。它允许基于一个或多个条件来选择执行哪一个代码块。

只有 if 的结构

最简单的条件结构是只有 if 的语句,如果条件为 True,则执行 if 下面的缩进代码块。使用方式如下:

if condition:
# 如果 condition 为 True,则执行这里的代码

与许多其他编程语言不同,Python 的 if-else 结构中,不但后面的代码块不需要使用括号来包围,就连判断条件也不需要使用括号包围。代替括号的是冒号和缩进:判断条件后面紧跟一个冒号,然后下面一行开始应该有一个统一缩进的,数行代码组成的代码块。比如:

x = 5
if x > 0:
print("条件满足了") # x > 0 时执行
print("x 是正数") # 这两行有相同缩进,属于同一代码块

带有 else 的结构

有时候,要让程序在条件不满足的时候,执行另一段代码,这就需要 if else 都用上了。使用方式如下:

if condition:
# 如果 condition 为 True,则执行这里的代码
else:
# 如果 condition 为 False,则执行这里的代码

比如:

x = -5
if x > 0:
print("x 是正数")
else:
print("x 是非正数")

需要注意的是,ifelse 下面的缩进代码块都不能缺失。有时候调试代码,可能希望暂时把 if 分支的代码块都注释掉,这样会导致程序出错。如果什么都不需要执行,可以使用 pass 关键字,它是一个占位语句,实际上什么都不做,比如:

x = -5
if x > 0:
pass
# print("x 是正数") 暂时不要执行
else:
print("x 是非正数")

带有 elif 的结构

有时候,要让程序检查多个条件,并在满足其中之一时执行对应的代码块。我们可以嵌套的 if else 实现所需功能,比如:

x = 0
if x > 0:
print("x 是正数")
else:
if x < 0:
print("x 是负数")
else:
print("x 是零")

这样的嵌套 if else 会导致程序缩进层次过多,降低可读性。为了简化代码,我们可以使用 elif 关键字代替 else if。用法是:

if condition1:
# 如果 condition1 为 True,则执行这里的代码
elif condition2:
# 如果 condition1 为 False 且 condition2 为 True,则执行这里的代码
else:
# 如果上述所有条件都为 False,则执行这里的代码

比如:

x = 0
if x > 0:
print("x 是正数")
elif x < 0:
print("x 是负数")
else:
print("x 是零")

多重条件

有时候,需要在多个条件都满足的情况下才做一件事,为了避免嵌套的 if else 语句,我们可以先使用逻辑运算符 (and, or, not) 组合多个条件,然后再使用 if else 结构,比如:

age = 25
if age >= 18 and age <= 35:
print("该年龄段的人是青年")

条件表达式

条件表达式,也经常被称为三元运算符或三元表达式,因为它需要三个输入值,分别是选择条件、条件为真时返回的值、条件为假时返回的值。条件表达式是 if else 语句的简化形式,用于在单行中进行简单的条件评估。它的基本格式是:

value_if_true if condition else value_if_false

当 condition 为真时,表达式的结果为 value_if_true;当条件为假时,结果为 value_if_false。

让我们通过几个例子来深入了解一下条件表达式的使用:

# 判断数字的正负
num = 10
label = "负数" if num < 0 else "非负数"
print(label) # 输出: 非负数

# 找出两个数中的较大值
a, b = 5, 8
max_value = a if a > b else b
print(max_value) # 输出: 8


# 根据年龄判断是否成年
age = 20
status = "成年" if age >= 18 else "未成年"
print(status) # 输出: 成年

有上面的例子可以看出,条件表达式能够在一行代码中就评估条件,这可以使代码更简洁。而且,它可以被使用在一些无法使用 if else 结构的地方,比如放在列表推导式中,其中原因可以参考:表达式与语句。虽然条件表达式很有优势,但如果需要判断的条件太过复杂,可能会导致代码难以阅读,这时候使用普通的 if else 语句可能更有可读性。

模式匹配

“模式匹配”(Structural Pattern Matching)语句也称为 match 语句,它按照预定的模式来匹配输入条件,并根据匹配结果执行相应的代码块。它可以看作是 if elif else 语句的加强版本。其基本语法如下:

match expression:
case pattern1:
# do something
case pattern2:
# do something else
...
case patternN:
# do something else
case _:
# default case, similar to 'else'

匹配变量值

模式匹配最简单的用法是匹配某个变量的值,然后跳入相应分支,类似其它一些编程语言中的 switch case 语句:

x = 5
match x:
case 10:
print("x 是 10")
case 20:
print("x 是 20")
case _:
print("x 是其它数")

同样,采用逻辑运算可以减少模式匹配结构的分支数量:

color = "绿"
match color:
case "红" | "绿" | "蓝":
print("RGB 颜色")
case _:
print("未知颜色")

在匹配列表时候,可以配合列表车拆包操作,匹配列表的具体长度和内容:

match some_list:
case []:
print("空列表")
case [a]:
print(f"只有一个元素: {a}")
case [a, b]:
print(f"两个元素: {a}{b}")
case [a, b, *rest, c]:
print(f"前两个元素为: {a}{b}, 最后一个元素为: {c}")

匹配系列数据

模式匹配不仅可以匹配单个的数据,也可以匹配一系列的数据,比如:

point = (2, 3)
match point:
case (0, 0):
print("原点")
case (0, y):
print(f"数据位于 Y 轴上: {y}")
case (x, 0):
print(f"数据位于 X 轴上: {x}")
case (x, y):
print(f"数据位于数轴之外的点: ({x}, {y})")
case _:
print("非法数据")

匹配数据类型

还可以基于数据类型进行匹配,这在类型检查或类型转换中非常有用。

value = "Hello, world!"
match value:
case int():
print("输入为整数")
case str() as s:
print(f"输入为字符串,长度为: {len(s)}")
case _:
print("输入不是整数或字符串")

没有 if else 的选择

有些编程语言是没有 if else 语句的,它们同样可以实现选择功能,比如可以利用元组的索引来实现类似功能。下面是一个带有索引的元组:

(a, b)[x]

上面程序的元组中有两个元素: a, b。当索引值 x 为 False 也就是 0 的时候,整个表达式返回元组的第 0 个元素,也就是 a;当索引值 x 为 True 也就是 1 的时候,整个表达式返回元组的第 1 个元素,也就是 b。

比如

# 判断数字的正负
num = 10
label = ("非负数", "负数")[num < 0]
print(label) # 输出: 非负数

# 找出两个数中的较大值
a, b = 5, 8
max_value = (b, a)[a > b]
print(max_value) # 输出: 8


# 根据年龄判断是否成年
age = 20
status = ("未成年", "成年")[age >= 18]
print(status) # 输出: 成年

如果索引是整数,或枚举类型数据,使用这种方式还可以代替简单的模式匹配语句,比如:

red, green, blue = 0, 1, 2

color = green
print(("红", "绿", "蓝")[color])

使用索引替代 if else 和 match 的优点是代码精简。缺点是不够直观,对于不熟悉的人,可能无法一下子领会程序逻辑。

关键字、表达式和语句

我们在介绍 Python 的编程方法时,经常会使用到一些术语,下面我们详细解释一下这些术语的含义。

关键字

在编程语言中,关键字(Keyword)是指被该语言赋予了特殊意义的词汇,用于定义语法和结构规则。关键字是编程语言的一部分,被预先定义在语言的规范中,我们在编程时,可以直接拿它们来用。由于关键字具有特殊的意义,它们作为保留字,只能用于特定用途,不能再被用作变量名、函数名或其他标识符。如果把关键字用作普通的标识符,比如变量名,将会导致语法错误。

在 Python 中,上文提到的 if, else, elif 等就是关键字,后文还将介绍到 for, while, break 等等很多其它的关键字。运行下面的代码可以打印出 Python 中所有的关键字:

import keyword
print(keyword.kwlist)

表达式

表达式(Expression)是计算机科学中的一个术语,指一个可以计算出一个值的代码单元。它是由变量、常量和操作符组成的序列,总是产生或返回一个结果值。表达式可以非常简单,如一个数学中的数字、变量,或者复杂,如整个数学公式或者函数调用。

比如下面是一些表达式的例子:

  • 3 + 4 返回 7
  • "Hello" + " " + "World" 返回 "Hello World"
  • my_function(2, 3) 返回函数 my_function 的运行结果
  • print("Hello World") 返回 None

有些函数看似没有返回结果,比如 print() 我们不会把它的返回值赋值给任何变量,比如 x = print(1)。但实际上,所有函数都有返回值,如果没有写明,则默认返回 None。

在 Python 中,我们可以把表达式放在任何需要一个值的地方,比如作为函数参数,作为 if 语句中的条件,作为其它表达式的一部分等。

表达式可以直接作为一行代码放在程序中。有些编辑环境在运行程序的时候,会把程序最后一行表达式的运算结果打印出来,以方便编程者查看。

语句

语句(Statement)是执行一个操作的完整命令。语句不像表达式那样返回值,它做的是指导程序去做某件事,例如声明一个变量、执行一个条件判断、这行一个循环等。

下面是一些语句的例子:

  • x = 3 + 2 赋值语句
  • if x > 0 条件控制语句

后文还将介绍到循环语句,函数定义语句等等。

语句在 Python 中是一个完整的句子,它不能再成为其它语句或表达式的一部分了。这也是为什么条件表达式可以放在一些无法放置 if else 语句的地方的原因。

如果使用分号分隔每个语句,那么可以在一行代码中书写多个语句。其它一些编程语言也是这样的,但这样并不符合 Python 的编程规范。我们在编写程序的时候,每一行就应该只放置一条语句,以提高程序的清晰度和可读性。