Python从入门到精通——第四章 程序流程控制
程序的基本结构有三种:顺序结构、选择结构和循环结构。
一.条件表达式
在选择结构和循环结构中,都需要根据条件表达式的值来确定下一步的执行流程。而在条件表达式中经常会用到关系运算符和逻辑运算符。
(一)关系运算符
Python语言中的关系运算符如下表所示:
运算符 | 描述 |
== | 等于 |
!= | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
Python语言中的关系运算符最大的特点是可以连用,这非常类似数学中的写法,与日常的理解完全一致。使用关系运算符的前提是操作数之间必须可以比较大小,如在一个字符串和一个数值之间比较大小就没有意义,Python语言也不支持这样的运算。
>>> a,b=10,50
>>> 0<a<b #表示a>0并且a<b,结果为True
True
>>> a==b #表示a和b的值是否相等,结果为False
False
>>> a>"BC" #数值不可与字符串比较大小,语句报错
TypeError: '>' not supported between instances of 'int' and 'str'
>>> 'ABC'>'ab' #字符串按对应字符的Unicode编码比较,结果为False
False
>>> 'Pyhon'<'python' #字符串按对应字符的Unicode编码比较,结果为True
True
(二)逻辑运算符
当需要形成更复杂的条件表达式的时候,会使用到逻辑运算符and(并且)、or(或者)和not(取反)。
>>> a,b=10,50
>>> a>10 and b<100 #表示a>10并且b<100,结果为False
False
>>> a>10 or b<100 #表示a>10活着b<100,结果为True
True
>>> not (a>10 and b<100) #将a>10并且b<100的结果取反,结果为True
True
(三)条件表达式
使用各种运算符可以构建不同的条件表达式,例如:
(1)假设有整数x,表示x为一个偶数。
x % 2 == 0
(2) 假设有整数x,表示x是3的倍数且个位上数字为5。
x % 3 == 0 and x % 10 == 5
(3)假设有三条线段,长度分别为a、b、c,表示 a、b、c能构成一个三角形。
(a+b>c) and (b+c>a) and (a+c>b)
(4)假设有某个年份year,则表示 year为闰年的条件是:如果year是4的倍数且不是100的倍数,或者year是400的倍数,那么year即为闰年。
(year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
这里,请注意关系运算符“==”和赋值符号“=” 的区别。
二.选择结构
(一)单分支结构:if语句
在Python中,单分支结构使用if
语句来实现条件判断,当条件为真时执行特定的代码块。
基本语法
if 条件表达式:# 条件为真时执行的代码块# 注意缩进(通常4个空格)
示例
1.简单条件判断
age = 18
if age >= 18:print("您已成年,可以进入")
2. 比较运算
score = 85
if score >= 60:print("恭喜您通过了考试")
3.逻辑运算
username = "admin"
password = "123456"
if username == "admin" and password == "123456":print("登录成功")
4.成员运算
fruits = ["apple", "banana", "orange"]
if "apple" in fruits:print("苹果在水果列表中")
注意事项
缩进:Python使用缩进来表示代码块,if语句下的代码必须缩进(通常4个空格)
冒号:if语句末尾必须有冒号(:)
条件表达式:可以是任何返回布尔值的表达式(True/False)
单行写法(不推荐,可读性差):
if age > 18: print("成年人")
单分支结构只处理条件为真的情况,如果条件为假,则跳过整个if代码块继续执行后续代码。
(二)双分支结构:if-else语句
在Python中,双分支结构使用if-else
语句来实现条件判断,根据条件真假分别执行不同的代码块。
基本语法
if 条件表达式:# 条件为真时执行的代码块
else:# 条件为假时执行的代码块
示例
1.简单条件判断
age = 17
if age >= 18:print("您已成年,可以进入")
else:print("您未成年,禁止进入")
2.数值比较
num = 10
if num % 2 == 0:print("这是一个偶数")
else:print("这是一个奇数")
3.字符串判断
user_type = "vip"
if user_type == "vip":print("欢迎尊贵的VIP用户")
else:print("欢迎普通用户")
4.布尔值判断
is_rain = True
if is_rain:print("今天下雨,记得带伞")
else:print("今天晴天,可以晾衣服")
注意事项
else不需要条件:else后面不需要也不能跟条件表达式
缩进规则:if和else下的代码块都必须正确缩进
冒号不可少:else语句末尾必须有冒号(:)
单行写法(不推荐,可读性差):
print("成年人") if age >= 18 else print("未成年人")
双分支结构确保无论条件真假,都会执行其中一个分支的代码,不会出现两个分支都被执行或都不执行的情况。
(三)多分支结构:if-elif-else语句
在Python中,多分支结构使用if-elif-else
语句来实现多个条件的判断,根据不同的条件执行对应的代码块。
基本语法
if 条件表达式1:# 条件1为真时执行的代码块
elif 条件表达式2:# 条件2为真时执行的代码块
elif 条件表达式3:# 条件3为真时执行的代码块
...
else:# 以上条件都不满足时执行的代码块
示例
1.成绩等级判断
score = 85
if score >= 90:print("优秀")
elif score >= 80:print("良好")
elif score >= 70:print("中等")
elif score >= 60:print("及格")
else:print("不及格")
2.BMI指数判断
bmi = 22.5
if bmi < 18.5:print("偏瘦")
elif 18.5 <= bmi < 24:print("正常")
elif 24 <= bmi < 28:print("超重")
else:print("肥胖")
3.工作日判断
day = "周三"
if day == "周一":print("工作日开始")
elif day == "周二" or day == "周三" or day == "周四":print("努力工作")
elif day == "周五":print("周末快来了")
else:print("周末愉快")
4.用户权限判断
user_role = "editor"
if user_role == "admin":print("拥有所有权限")
elif user_role == "editor":print("可以编辑内容")
elif user_role == "viewer":print("只能查看内容")
else:print("无权限访问")
注意事项
执行顺序:条件判断从上到下依次进行,一旦某个条件满足,执行对应代码块后就会跳出整个结构
else可选:else分支不是必须的,可以只有if和elif
条件互斥:多个条件之间应该是互斥关系,避免条件重叠
缩进一致:所有代码块必须保持相同的缩进级别(通常4个空格)
性能考虑:将最可能满足的条件放在前面可以提高效率
多分支结构特别适合需要处理多种不同情况的场景,比嵌套的if-else语句更加清晰易读。
(四)嵌套的if结构
嵌套if结构是指在if或else代码块中再包含if语句的结构,用于处理更复杂的条件判断场景。
基本语法
if 条件表达式1:# 外层条件为真时执行的代码if 条件表达式2:# 内层条件为真时执行的代码else:# 内层条件为假时执行的代码
else:# 外层条件为假时执行的代码if 条件表达式3:# 另一个内层条件为真时执行的代码
示例
示例1:登录验证系统
username = "admin"
password = "123456"if username == "admin":if password == "123456":print("登录成功")else:print("密码错误")
else:print("用户名不存在")
示例2:成绩等级细分
score = 87if score >= 60:if score >= 90:print("优秀")elif score >= 80:print("良好")else:print("及格")
else:print("不及格")
示例3:购物折扣系统
is_member = True
total = 1200if is_member:if total > 1000:print("享受会员8折优惠")elif total > 500:print("享受会员9折优惠")else:print("享受会员95折优惠")
else:if total > 1000:print("享受普通客户9折优惠")else:print("无折扣优惠")
示例4:闰年判断
year = 2024if year % 4 == 0:if year % 100 == 0:if year % 400 == 0:print(f"{year}年是闰年")else:print(f"{year}年不是闰年")else:print(f"{year}年是闰年")
else:print(f"{year}年不是闰年")
注意事项
缩进层级:每层嵌套需要增加一级缩进(通常4个空格)
可读性:过度嵌套会降低代码可读性,建议嵌套不超过3层
替代方案:考虑使用逻辑运算符(
and
,or
)或函数来简化嵌套结构条件顺序:将最可能满足的条件放在前面可以提高效率
括号使用:复杂条件可以使用括号提高可读性
简化嵌套的建议
当遇到深层嵌套时,可以考虑以下替代方案:
1.使用提前返回(在函数中)
def check_year(year):if year % 4 != 0:return Falseif year % 100 != 0:return Truereturn year % 400 == 0
2.使用布尔表达式组合
is_leap = (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
3.将部分逻辑提取为函数
嵌套if结构虽然功能强大,但应当谨慎使用,避免创建难以维护的"箭头代码"。
三.循环结构
(一)for语句
for语句用一个循环控制器(Python语言中称为迭代器)来描述其语句块的重复执行方式。
基本语法
for 变量 in 迭代器:语句块
其中,for和in都是关键字。语句中包含了三个部分,其中最重要的就是迭代器。由关键词for语句开始的行称为循环的头部,语句块称为循环体。与if结构中的语句快情况类似,这里语句块中的语句也是下一层的成分,同样需要缩进,且语句块中各个语句的缩进量必须相同。
迭代器是Python语言中的一类重要机制,一个迭代器描述一个值序列。在for语句中,变量按顺序取得迭代器表示的值序列中的各个值,对每一个值都将执行语句块一次。由于变量取得的值在每一次循环中不一定相同,因此虽然每次循环都执行相同的语句块代码,但执行的效果却随变量取值的变化而变化。
常见用法
- 遍历列表
fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:print(fruit)
- 遍历字符串
for char in "Python":print(char)
- 使用range()函数
range()是Python语言中的一个内置函数,调用这个函数就能产生一个迭代序列,因此适合放在for语句的头部。range()函数有以下几种不同的调用方式:
(1)range(n)。range(n)得到的迭代序列为:0,1,2,3,...,n-1。例如,range(100)表示序列0,1,2,3,...,99。当n<=0的时候序列为空。
(2)range(m,n)。range(m,n)得到的迭代序列为:m,m+1,m+2,...,n-1。例如,range(11,16)表示序列11,12,13,14,15。当m>=n的时候序列为空。
(3)range(m,n,d)。range(m,n,d)得到的迭代序列为:m,m+d,m+2d,...,按步长值d递增,如果d为负则递减,直至那个最接近但不包括n的等值差。因此,range(11,16,2)表示序列:11,13,15;range(15,4,-3)表示序列:15,12,9,6。这里的d可以是正整数,也可以是负整数,正数表示增量,而负数表示减量,也有可能出现空序列的情况。
for i in range(5): # 0到4print(i)for i in range(2, 6): # 2到5print(i)for i in range(0, 10, 2): # 0到9,步长为2print(i)
(二)while语句
在for语句中关注的是迭代器生成的遍历空间,然而有的时候循环的初值和终值并不明确,但是有清晰的循环条件,这时采用while语句会更为方便。
while语句中,用一个表示逻辑条件的表达式来控制循环,当条件成立的时候反复执行循环体,直到条件不成立的时候循环结束。
基本语法
while 条件表达式:语句块
示例
count = 0
while count < 5:print(count)count += 1
(三)循环控制语句
1.break语句
立即退出整个循环
for i in range(10):if i == 5:breakprint(i) # 只打印0-4
2.continue语句
跳过当前迭代,进入下一次循环
for i in range(10):if i % 2 == 0:continueprint(i) # 只打印奇数
3.pass语句
空操作,占位符
for i in range(5):pass # 什么也不做
(四)循环的else子句
现在有两种方式退出for循环或者while循环,一是循环条件不成立或序列遍历结束;另一种是在循环过程中遇到了break语句。在for和while循环结构中,都可以带有else子句,从而对两种退出循环的方式做不同的处理。如果循环是因为条件表达式不成立或者是序列遍历结束而自然退出时则执行else结构中的语句,如果循环是因为break语句导致提前结束时则不会执行else结构中的语句。
for i in range(3):print(i)
else:print("循环正常结束")# 输出:
# 0
# 1
# 2
# 循环正常结束
(五)嵌套循环
在一个循环体内又包含一个完整的循环结构,称为循环的嵌套。这种语句结构称为多重循环结构。内层循环中还可以包含新的循环,形成新的多重循环结构。
for i in range(3):for j in range(2):print(f"i={i}, j={j}")
(六) 列表推导式
squares = [x**2 for x in range(10)] # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
(七) 迭代器与生成器
迭代器协议:
__iter__()
和__next__()
方法生成器函数:使用
yield
关键字
def count_up_to(max):count = 1while count <= max:yield countcount += 1counter = count_up_to(5)
for num in counter:print(num)
(八)常见循环模式
1.枚举循环(同时获取索引和值)
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits):print(index, fruit)
2.并行遍历多个序列
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
for name, age in zip(names, ages):print(f"{name} is {age} years old")
3.字典遍历
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}
for key in person: # 遍历键print(key)for value in person.values(): # 遍历值print(value)for key, value in person.items(): # 遍历键值对print(key, value)