流程控制
大纲前言
条件判断语句if语句
elif语句
else语句
嵌套的条件语句
用字典代替多个if/else
占位语句
循环语句for循环语句
while循环语句
主动结束循环
跳过当前循环
鲜为人知的else尾巴
总结
前言
至今为止,我们做的程序都是顺序结构的,没有任何逻辑,只有一股脑地从上到下一句执行完又到下一句,下面我们来学习流程控制语句,以改变我们程序的执行顺序,让它变得更有趣些
条件判断语句"如果能重来,我要选李白,否则我就继续当李荣浩。",这就是条件判断,它根据条件的不同,使程序走向不同的流程
if语句
在python或绝大多数编程语言中,用if表示如果,它的格式如下if :
if内语句1
if内语句2
if外语句3
冒号后回车,再以4个空格缩进为代码块,以上语句1、2都在代码块内,但语句3不在if代码块内
如果条件成立(条件为布尔值True时),则先执行其代码块内的代码,否则将不执行
如果以代码的方式来表示李荣浩的那句歌词,大概长下面这个样子# 能重来这个条件是成立的
again = True
if again:
print('我要选李白')
print('几百年前做的好坏 没那么多人猜')
print('至少我还能写写诗来澎湃 逗逗女孩')
print('创作也能到那么高端 被那么多人崇拜')
print('继续唱')
# 把能重来这个条件设为不成立
again = False
if again:
print('我要选李白')
print('几百年前做的好坏 没那么多人猜')
print('至少我还能写写诗来澎湃 逗逗女孩')
print('创作也能到那么高端 被那么多人崇拜')
print('再继续唱')
结果如下我要选李白
几百年前做的好坏 没那么多人猜
至少我还能写写诗来澎湃 逗逗女孩
创作也能到那么高端 被那么多人崇拜
继续唱
再继续唱
可以看到当我们把条件设为不成立后,第二个if代码块内的代码并不会执行
事实上,在python中,if并不需要一定接收布尔值,如果接受的是非布尔值,解释器会自动将它转为布尔值,例如a = '条件'
# 以字符串a作为条件
if a:
print('条件成立!')
虽然字符串"条件"并不是布尔值,但是解释器会把它自动转为布尔值,您可以通过内置函数bool把一个非布尔值的类型主动转为布尔值is_ok = bool('条件')
print(is_ok) # True
print(type(is_ok)) #
在python中,空值 None 、整数 0 、空字符串 "" 、空列表 [] 、空元组 tuple() 、空字典 {} 和空集合 set(),它们被转化为布尔值时,皆被认为是False,其余都为True# 空值None
print(bool(None)) # False
# 整数0
print(bool(0)) # False
# 空字符串
print(bool('')) # False
# 空列表
print(bool([])) # False
# 空元组
print(bool(tuple())) # False
# 空字典
print(bool({})) # False
# 空集合
print(bool(set())) # False
在条件语句中有如下常用的操作运算符,它们的结果类型都是布尔值操作符作用例子结果==比较左右两者是否相等1==1True
!=比较左右两者是否不相等1!=2True
>比较左边值是否大于右边值2>3False
>=比较左边值是否大于或等于右边值3>=3True
<=比较左边值是否小于或等于右边值2<=3True
not表示对值进行取反,将True变为False 或 将False变为Truenot 1False
还有两个操作符,但它们的结果类型取决于操作数的类型操作符作用例子结果and顺序查看左右两者的布尔值是否为True,直到遇到False或最后一个时即退出,并返回退出时的值0 and 1或1 and 0皆为0
or顺序查看左右两者的布尔值是否为True,直到遇到True或最后一个时即退出,并返回退出时的值0 or 1或1 or 0皆为1
可以通过以下例子来加深理解# and的例子
a = 1 and 'hello' # 先看1的布尔值为True,继续看'hello'的布尔值也为True,到达最后一个,退出,所以a='hello'
b = 0 and 'no' # 先看0的布尔值为False,退出,所以b=0
c = {1} and [] # 先看非空集合的布尔值为True,继续看空列表的布尔值为False,退出,所以c=[]
# or的例子
d = 0 or '' # 先看0的布尔值为False,继续看空字符串的布尔值也为False,到达最后一个,退出,所以d=''
e = [1] or (1,) # 先看非空列表的布尔值为True,退出,所以e=[1]
f = tuple() or 2 # 先看空元组的布尔值为False,继续看2的布尔值为True,退出,所以f=2
# 结合if来使用
number = 6
print(6 > 5) # 6大于5,True
print(6 < 10) # 6小于10,True
# if的条件相当于True and True,所以条件当然成立了
if 6 > 5 and 6 < 10:
print('6比5大,但比10小')
elif语句
elif是else if的简写,它可以与if组成多条件判断,它表示再如果,elif不能脱离if单独使用,格式如下if 条件1:
语句1
语句2
elif 条件2:
语句3
语句4
elif 条件3:
语句5
语句6
例如做一个根据考试分数来评价是否优秀的示例程序# 判断成绩
# 85分以上为优秀
# 60~85分为中等
# 60以下为不及格
# 分数为61
score = 61
if score >= 85:
print('优秀')
elif 60 <= score < 85:
print('中等') # 打印出这一句
elif score < 60:
print('不及格')
60 <= score < 85这一句,它等价于(60 <= score) and (score < 85),这里小括号加与不加效果都一样,因为是比较运算符先结合,再轮到and操作符
注意条件判断是顺序判断的,如果某个条件成立了,无论其后条件成立与否,都不会去执行了,例如score = 61
if score > 60:
print('中等') # 打印出这句后,退出条件判断
elif score >= 85:
print('优秀')
print('结束') # 结束
所以顺序很重要
else语句
else 表示 否则,当所有的if或elif的条件都不成立时,将会执行else内的代码块
else也不能脱离if单独使用,但与elif不同,它还可以与另外两个语句搭配使用,后面将会介绍到
所以条件判断语句的完整格式如下:if 条件1:
语句1
语句2
elif 条件2:
语句3
语句4
else:
语句5
语句6
当条件1和2都不成立时,else内的语句5、6将会被执行
利用else,我们可以将分数判断程序改写成score = 99
if score >= 85:
print('优秀') # 打印出这一句
elif score >= 60:
print('中等')
else:
print('不及格')
是不是更加的简洁了?
注意不能把score >= 60放在第一个条件中,否则分数99永远只会打印出中等
我们可以利用内置函数input来让用户自己输入分数,在此之前要注意input获取到的值类型是字符串,所以得先把字符串转为数字
可以用内置函数int将字符串转为整数,或用内置函数float将字符串转为浮点数,前提是所输入的字符串必须可以被转化为数字,否则将会报错number = input('输入一个数字:') # 输入8后回车
print(number) # 8
print(type(number)) #
# 利用内置函数int将它转为整数
int_number = int(number)
print(int_number) # 8
print(type(int_number)) #
# 利用内置函数float将它转为浮点数
float_number = float(number)
print(float_number) # 8.0
print(type(float_number)) #
利用input函数,分数判断程序可以改写成这样score = input('请输入您的分数:')
score = float(score)
if score >= 85:
print('优秀')
elif score >= 60:
print('中等')
else:
print('不及格')
嵌套的条件语句
您可以将if...elif...else条件语句嵌套到另外一个if...elif...else中
注意4个空格表示一个代码块,相同缩进数的语句在一起组成一个语句块
格式大概长下面这样if 条件1:
语句
if 条件2:
语句
elif 条件3:
语句
else:
语句
elif 条件4:
语句
else:
语句
利用嵌套条件语句,我们让分数的划分更细一点score = float(input('请输入您的分数:'))
if score >= 85:
if score >= 95:
print('极优秀')
else:
print('优秀')
elif score >= 60:
if score >= 80:
print('良好')
elif score >= 70:
print('中等')
else:
print('及格')
else:
print('不及格')
可以通过Python Tutor代码执行可视化网站 http://pythontutor.com/visualize.html,来看到程序的每一步执行情况
例如输入分数为75
用字典代替多个if/else
试想有以下代码,根据数字1~7来判断今天是星期几num = int(input('请输入数字1~7:'))
if num == 1:
day = '星期一'
elif num == 2:
day = '星期二'
elif num == 3:
day = '星期三'
elif num == 4:
day = '星期四'
elif num == 5:
day = '星期五'
elif num == 6:
day = '星期六'
elif num == 7:
day = '星期天'
else:
day = '未知'
print(day)
如何来让它变得更简洁些呢?
在某些编程语言中,可以利用switch...case来简化,但是python并没有switch语句,但是我们可以利用字典键值对的特性来达到同样的目的num = int(input('请输入数字1~7:'))
day_dict = {1:'星期一',
2:'星期二',
3:'星期三',
4:'星期四',
5:'星期五',
6:'星期六',
7:'星期天'}
print(day_dict[num])
貌似简洁多了
但是有个问题,如果用户输入的不是1~7数字,将会报错,上面的代码并没有做到else的效果
可以巧妙利用字典的get方法来达到else的效果,它的格式像这样dict.get(self, key, default=None, /)a = {'a':1, 'b':2}
# 下面这行将会报错
# print(a['c'])
# 利用字典get方法来获取键'b'的值
print(a.get('b')) # 2
# 但当不存在键时,会返回空值None
print(a.get('c')) # None
# 可以为get方法添加一个默认值
print(a.get('c', '没有哦')) # 没有哦
所以我们可以把最后一行代码改成print(day_dict.get(num, '未知')),效果就一模一样了
占位语句
因为python以缩进为代码块的特性,python有一个其他编程语言都没有的语句,它叫做占位语句
占位语句用pass标识,它表示通过的意思,就是告诉python解释器,我在这里占着茅坑不拉屎,你不用管我,继续往下走
假如您的if语句的内代码块啥也不做,或者暂时还没想好要做些啥,pass就派上用场了num = 10
if num > 5:
# 我还没想好大于5时,if内代码块要做些啥
# 先来个pass语句占着位置吧
# 因为如果不占个位,就会报语法错误
pass
else:
print('小于或等于5哦')
循环语句
请用python算出1+2+3的和>>> 1+2+3
6
so easy
请再用python算出1+2+3.......+10的和
>>> 1+2+3+4+5+6+7+8+9+10
55
请再用python算出1+2+3.......10000的和
所以这时候,循环就派上用场了!
在python中,有两种循环,它们分别是for循环与while循环
for循环语句
for循环的格式是for 变量名 in 可迭代对象
在python的基本数据类型中,字符串str、列表list、元组tuple、集合set、字典dict这5个皆为可迭代类型(对象),也就是说,我们可以通过for...in循环来遍历其内成员(元素)# 遍历字符串
for s in 'abc':
# 字符串内的每一个字符'a'、'b'、'c'都会依次赋值给变量s
print(s)
# 遍历列表
for i in [1,2,3]:
# 列表内的成员1、2、3会依次赋值给变量i
print(i)
# 遍历元组、集合的效果和遍历列表基本一致,就不举例了
pass
# 与其它基本数据类型不一样,遍历字典时,会把字典的键赋值给变量,而不是字典的值
d = {'a':1, 'b':2}
for k in d:
print(k) # 依次打印a与b
print(d[k]) # 通过键获取对应的值
# 可以通过字典的values方法,直接遍历字典的值
for v in d.values():
print(v) # 依次打印1、2
# 可以通过字典的keys方法,遍历字典的键,这里与直接遍历字典的效果是一样的
for k in d.keys():
print(k) # 依次打印a与b
# 可以通过字典的items方法,同时遍历字典的键与值
for k, v in d.items():
print(k,v) # 先打印a与1,再打印b与2
这里您可能不理解items那一段是什么鬼,这里涉及到python变量解包的知识# 在一章中,我们学过多个变量的赋值
a, b = 1, 2
print(a, b) # 1 2
# ok, 没问题
# 在那一章中,我们知道1,2这样会被python解释器当作是元组
c = 1, 2
print(c) # (1, 2)
print(type(c)) #
# 所以一开始的a,b=1,2等价于
a, b = c
print(a, b) # 1 2
这就叫变量解包,我们知道了多个变量赋值的真相!
通过内置函数list,我们可以将可迭代对象转化为列表d = {'a':1, 'b':2}
e = list(d.items())
print(e) # [('a', 1), ('b', 2)]
# 看到了吗
# 一个列表里,每个元素都是一个长度为2的元组
# 这样试试
for both in e:
print(both) # 先打印('a', 1),再打印('b', 2)
# 加上我们的变量解包呢?
for key, value in e:
print(key,value)
# ok,现在明白了
for循环的基友range
内置函数range是for循环的好基友,range是Range Rover(路虎)的range,它中文意思是一段范围,我们可能暂时玩不起Range Rover,但是我们必须得把range给玩溜了,才能玩好for循环
range函数有两种格式,它们都返回一个可迭代对象range(stop) -> range object
range(start, stop[, step]) -> range object
直接上例子# 只给一个参数,表示结束位置(不包含),它表示[0~结束位置)这段范围
print(list(range(3))) # [0, 1, 2]
# 传入两个参数,第一个参数表示起始位置(包含),第二个参数表示结束位置(不包含),它表示[起始位置~结束位置]这段范围
print(list(range(1, 6)) # [1, 2, 3, 4, 5]
# 传入三个参数,第一、二个参数和上面一样,第三个表示步长,即每次跨多少步
# 当传入两个参数时,步长默认为1
# 下面表示范围从[1~10],步长为2,所以得到了1到10内所有奇数组成的列表
print(list(range(1, 10, 2))) # [1, 3, 5, 7, 9]
# 与for循环配合
for i in range(3):
print(i) # 依次打印1~3
所以1+2+3.......10000的和,我们可以通过for与range的配合求出# 一开始将总数设为0
sum = 0
for num in range(1, 10001):
# 将1~10000的每个数累加到sum上
sum = sum + num
print(sum) # 50005000
解放双手,美滋滋!
我们再通过观察for循环的每一步走向来更深一步了解它
for循环的又一基友enumerate
内置函数enumerate作用于可迭代对象,比如利用它,可以同时遍历列表的数据和数据的下标(索引)
函数的格式长这样enumerate(iterable, start=0)
直接上例子a = ['a', 'b', 'c']
for index, data in enumerate(a):
print(index, data)
# 顺序打印
# 0 a
# 1 b
# 2 c
将列表传给函数enumerate后,它的返回值和字典的items方法返回值有点像a = ['a', 'b', 'c']
b = enumerate(a)
# 利用内置函数list将可迭代对象转为列表看看
print(list(b)) # [(0, 'a'), (1, 'b'), (2, 'c')]
将enumerate的返回值转成列表后,可以看出,这是所有元素都是长度为2元组的列表,其中,元组第一个值为列表元素的下标,第二个值为对应的元素
while循环语句
第二种循环叫做while,它的格式长下面这样while 条件:
语句1
...
语句N
当条件满足时,将不断循环执行代码块内容,直至条件不满足时正常退出循环
比如同样计算1+2+3.......10000的和,用while循环的话,可以这样sum = 0
num = 1
while num <= 10000:
sum = sum + num
num = num + 1
print(sum) # 50005000
通过动画来看流程是这样的
主动结束循环
至今为止,无论是for循环还是while循环,它的结束都是正常结束的,要么可迭代对象已迭代完毕退出,要么条件不满足退出
我们可以通过break语句来主动退出循环
当while的条件为真时,将进行下一次循环,如果while的条件永远是True的话,就变成了死循环,像下面一样while True:
print('你好帅啊')
如果您有耐心,机器将会日夜不停地赞美您,如果您感到厌烦,可以通过按键Ctrl+C来终止它
利用break语句,当赞美了两次后,主动退出循环times = 0
while True:
if times == 2:
# 当times变量等于2时,break退出循环
break
print('你好帅啊')
times = times + 1
print('谢谢,但是地球人都知道')
跳过当前循环
跳过当前用continue语句,它表示继续的意思,当在循环中遇到continue后,其后的语句不会执行,而是继续下一次循环
例如,当数字等于2时,不进行打印for i in range(1, 4):
if i == 2:
# 遇到continue后,其后的语句不会执行,而是继续下一次循环
continue
print(i)
通过动画来看流程是这样的
鲜为人知的else尾巴
话说"花心"的else不但可以与if条件语句进行搭配,它还可以与循环进行搭配,所以我们揭开了两种循环的面纱,看到了它们的最终面貌
for循环for in :
else:
while循环while :
else:
else下的代码块只会在循环正常退出时执行,所谓正常退出,是指非break主动退出循环的情况下,循环正常结束退出
我们在循环中通过动画看两种循环结束情况的执行逻辑正常结束循环
break主动结束循环
总结
熟练掌握条件判断语句与循环语句,将让您的程序更有逻辑性