【Python零基础入门教程】4-3.流程控制

流程控制

大纲

  • 前言
  • 条件判断语句
    • 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==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 11 and 0 皆为0
or 顺序查看左右两者的布尔值是否为True,直到遇到True或最后一个时即退出,并返回退出时的值 0 or 11 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语句

elifelse 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 表示 否则,当所有的ifelif的条件都不成立时,将会执行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

【Python零基础入门教程】4-3.流程控制_第1张图片

用字典代替多个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])

貌似简洁多了

【Python零基础入门教程】4-3.流程控制_第2张图片

但是有个问题,如果用户输入的不是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零基础入门教程】4-3.流程控制_第3张图片

请再用python算出1+2+3.......+10的和

【Python零基础入门教程】4-3.流程控制_第4张图片

>>> 1+2+3+4+5+6+7+8+9+10
55

请再用python算出1+2+3.......10000的和

【Python零基础入门教程】4-3.流程控制_第5张图片

所以这时候,循环就派上用场了!

在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

内置函数rangefor循环的好基友,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循环的每一步走向来更深一步了解它

【Python零基础入门教程】4-3.流程控制_第6张图片

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

通过动画来看流程是这样的

【Python零基础入门教程】4-3.流程控制_第7张图片

主动结束循环

至今为止,无论是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('谢谢,但是地球人都知道')

【Python零基础入门教程】4-3.流程控制_第8张图片

跳过当前循环

跳过当前用continue语句,它表示继续的意思,当在循环中遇到continue后,其后的语句不会执行,而是继续下一次循环

例如,当数字等于2时,不进行打印

for i in range(1, 4):
    if i == 2:
        # 遇到continue后,其后的语句不会执行,而是继续下一次循环
        continue
    print(i)

通过动画来看流程是这样的

【Python零基础入门教程】4-3.流程控制_第9张图片

鲜为人知的else尾巴

话说"花心"的else不但可以与if条件语句进行搭配,它还可以与循环进行搭配,所以我们揭开了两种循环的面纱,看到了它们的最终面貌

for循环

for  in :
    
else:
    

while循环

while :
    
else:
    

else下的代码块只会在循环正常退出时执行,所谓正常退出,是指非break主动退出循环的情况下,循环正常结束退出

我们在循环中通过动画看两种循环结束情况的执行逻辑

  1. 正常结束循环

    【Python零基础入门教程】4-3.流程控制_第10张图片

  2. break主动结束循环

    【Python零基础入门教程】4-3.流程控制_第11张图片

总结

熟练掌握条件判断语句与循环语句,将让您的程序更有逻辑性

你可能感兴趣的:(【Python零基础入门教程】4-3.流程控制)