至今为止,我们做的程序都是顺序结构的,没有任何逻辑,只有一股脑地从上到下一句执行完又到下一句,下面我们来学习流程控制语句,以改变我们程序的执行顺序,让它变得更有趣些
"如果能重来,我要选李白,否则我就继续当李荣浩。",这就是条件判断,它根据条件的不同,使程序走向不同的流程
在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==1 |
True |
!= |
比较左右两者是否不相等 | 1!=2 |
True |
> |
比较左边值是否大于右边值 | 2>3 |
False |
< |
比较左边值是否小于右边值 | 3<2 |
False |
>= |
比较左边值是否大于或等于右边值 | 3>=3 |
True |
<= |
比较左边值是否小于或等于右边值 | 2<=3 |
True |
not |
表示对值进行取反,将True变为False 或 将False变为True | not 1 |
False |
还有两个操作符,但它们的结果类型取决于操作数的类型
操作符 | 作用 | 例子 | 结果 |
---|---|---|---|
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
是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
表示 否则
,当所有的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
试想有以下代码,根据数字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 变量名 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 条件:
语句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
不但可以与if
条件语句进行搭配,它还可以与循环进行搭配,所以我们揭开了两种循环的面纱,看到了它们的最终面貌
for循环
for in :
else:
while循环
while :
else:
else
下的代码块只会在循环正常退出时执行,所谓正常退出,是指非break主动退出循环的情况下,循环正常结束退出
我们在循环中通过动画看两种循环结束情况的执行逻辑
熟练掌握条件判断语句与循环语句,将让您的程序更有逻辑性