到目前为止,我们写的Python程序还都是简单的顺序结构,就是所有的代码按照从上到下的顺序逐行执行。要编写简单的程序没问题,如果程序稍微需要一些逻辑处理,就力不从心了。我们在Scratch编程中已经使用过“如果…那么…”和“重复执行…”、“重复执行直到…”这一类的控制积木,它可以让我们的程序根据条件的变化执行不同的逻辑。例如:要编程找出1-1000之间所有的奇数,如果你没有逻辑判断的话,怎么写呢?
这一节,我们来看看Python中怎么使用分支、循环来实现程序执行流程的控制。
一、分支结构
我们在学习Scratch的过程中,使用过下面的积木:
第一种“如果…那么”实现的是单分支结构,如果指定的条件符合,就执行它包括的代码。第二种“如果…那么…否则…”是二分支结构,根据指定条件决定它包括的两块代码中哪一块被执行。后两种是第一、第二种分支结构的组合,它们之间可以任意地嵌套来实现更复杂的程序逻辑。
在Python中,我们除了实现“单分支”、“二分支”结构,还可以实现“多分支结构”,分支之间也可以嵌套。
我们逐一来讲解:
1、单分支结构:
代码格式:
if <判断条件>:
<语句块>
“if” 这个英文单词是“如果”的意思,也就是如果<判断条件>符合(这里的判断条件不用带<>括号),就执行它包含的语句块,否则就跳过这条if语句执行后面的代码了。这里有三点要注意: 1、if <判断条件> 后面有一个英文的冒号“:”千万不要漏写; 2、<判断条件>可以是算术表达式、关系表达式或逻辑表达式等。 3、<语句块>是向内缩进的,可以是多条语句,它们的缩进要一致。
“缩进”是Python用来实现代码包含和层次关系的方式,前面我们写代码的时候,要求不能在前面加空格,让所有代码都顶格写,就是要它们保持缩进一致;现在我们写 if
语句的时候,就得注意它“包含”的语句块,必须是缩进的,一般我们写完条件后的冒号之后,编辑器就会自动帮我们缩进,如果你的编辑器不支持缩进,或者你要修改现有代码,就要注意缩进。缩进一般用键盘上的Tab键实现,也可以用四个空格。
示例:
a = int(input('请输入一个数字:'))
if a > 0:
print('你输入的是正数')
print('判断结束')
缩进还可以分为单层缩进和多层,现在我们写单分支结构用单层缩进,如果存在嵌套,那就得使用多层缩进来体现嵌套的关系了。
2、二分支结构
格式:
if <判断条件>:
<语句块a>
else:
<语句块b>
与单分支结构相比,二分支结构就是多了后面的“else:”(“else”就是英语“否则”的意思)。使用二分支结构,实现的就是“非此即彼”的判断,如果条件符合,执行语句块a,不符合就执行语句块b。我们常用的密码判断就会使用这种语句:
name = input('请输入用户名:')
password = input('请输入登录密码:')
if name == '乐乐' and password == 'lele':
print('登录成功')
else:
print('你输入的用户或密码不正确!')
3、多分支结构
掌握了二分支,很容易理解多分支结构。多分支结构用于判断条件有多个可能值的情况。 格式:
if <判断条件1>:
<语句块1>
elif <判断条件2>:
<语句块2>
elif <判断条件3>:
<语句块3>
elif <判断条件4>:
<语句块4>
……
else:
<语句块>
这种多分支结构的执行流程是:如果判断条件1符合,执行语句块1;否则判断条件2,如果符合执行语句块2;否则判断条件3……这里的elif语句你可以使用多个。如果所有上面的分支都不符合的时候,就执行else语句块的内容。else语句块是可选的,如果没有最后的else,前面的条件也都不符合,那么这个多分支结构就什么也不执行。
多分支结构最典型的示例就是判断成绩了:
score = int(input('请输入成绩(0-100之间的数字):'))
if score > 90:
print('你的成绩优秀,恭喜!')
elif score > 80:
print('你的成绩良好,继续努力!')
elif score >= 60:
print('你的成绩合格,请加油!')
else:
print('很遗憾你没有及格!')
4、分支的嵌套
与Scratch一样,Python可以把分支结构嵌套起来使用。不过这时一定要注意缩进。 我们用一个示例说明,在这个示例中,我们根据性别和跳远成绩来判断是否合格,男生合格标准是185cm,女生是146cm:
sex = input('请输入你的性别(男或女)')
score = int(input('请输入跳远距离(0-100之间的数字):'))
if sex == '男':
if score >= 185:
print('你的跳远成绩合格!')
else:
print('很遗憾你的跳远成绩不合格!')
else:
if score >= 146:
print('你的跳远成绩合格!')
else:
print('很遗憾你的跳远成绩不合格!')
这里我们看到,判断成绩的分支是包括在判断性别的分支当中的,所以缩进了一层,而不同成绩的输出则又缩进了一层。在海龟编辑器中,你可以看到同一层级的缩进前面有一条竖线,这样方便你查看缩进是否正确。
5、分支结构的注意事项
- 判断条件的表达式,值不一定非要是True和False。0、0.0、空字符串、空列表、空元组、空集合、空字典这些都会被认为是False。反之,非零值、非空字符串、非空列表……这些则认为是True。
- in和not in这种成员运算符也可以用于判断条件;
- 二分支结构中肯定有一条分支会被执行;
- 多分支结构中最多只有一条被执行。
二、循环结构
循环结构对应着Scratch中的“重复执行”:
其中,第一个是“无限循环”,除非你用停止脚本积木,或者手动停止程序,否则它会一直执行下支;第二种属于“计数循环”,重复指定的次数后自己停止;最后一种则是“条件循环”,当指定的条件不成立时一直重复,条件成立时退出循环。
Python中对循环的实现提供了更强大的支持,从大类上可以分为for循环和while循环两种,我们分别来介绍它们的使用场景。
1、for循环
for循环通常用于遍历可迭代对象。它的格式如下:
for <循环变量> in <可迭代对象>:
<循环体>
什么是可迭代对象呢?列表、元组、字符串这些类型,本身都包括了一组其它数据元素,我们可以按照顺序逐一地访问它的子元素,这类对象就是可迭代对象,逐一访问它们的子元素称为遍历。除了列表、元组和字符串,我们常用的可迭代对象还有range()函数的返回值等。下面说明这些场景的用法。
计数循环
计数循环要用到range()函数,range()函数语法如下: range(start, end, step) – start:计数的起始值,可以省略,省略时默认为0.如 range(5)等价于range(0,5,1) – end:计数的结束值(但不包括结束值),例如range(1,5)会生成序列1、2、3、4,不包括5; – step:步长,默认为1,可以为负数。如range(0,6,2)会生成序列0、2、4,不包括6; 使用range()函数至少应该传递一个参数。当range()函数中只有一个参数时,这个参数代表的就是计数的结束值;当range()函数中有两个参数时,两个参数分别表示开始计数和结束计数,步长为1;如果三个参数,则分别代表开始计数值、结束计数值和步长。
示例
# 求1+2+3+…+99+100 的值
s = 0
for i in range(1,101):
s+=i
print('1+2+3+…+99+100=%d'%s) # 使用了字符串格式化语法
注意,在range()函数后是一个英文冒号。循环体是通过缩进一层来表示它和for语句的包含关系的。你会发现这段代码和Scratch中的重复执行…次有相似之处,它可以精确地控制执行的次数。
列表遍历
直接看示例:
heros = ['关羽','黄忠','赵云','张飞','魏延']
for i in heros:
print(i)
我们可以这么理解,执行上面的代码,相当于每次从列表中取出一个英雄的名字,送到循环体里去执行(打印名字)。大家排着队,等到列表中每一个元素都打印出来了,循环就结束了。列表中有多少个元素,循环体就执行了多少次。
要遍历列表,我们还可以用range函数,在循环体中用列表索引来访问对应的元素:
heros = ['关羽','黄忠','赵云','张飞','魏延']
for i in range(len(heros)):
print(heros[i])
在这个for循环中,我们用列表的长度调用了range()函数,前面说过,只有一个参数的时候,range()函数会把它当做结束值,也就是说,列表中有5个元素,所以会生成从零开始的序列0、1、2、3、4,用索引的方式正好取出第0、1、2、3、4个元素来打印。
比较上面两种方法,第一种是Scratch中没有的,可以非常方便地遍历列表中的元素;第二种则类似于我们以前访问Scratch中列表的方法,用一个变量做索引,每次取出列表对应的元素。如果只是要依次遍历列表内容,肯定第一种方法更方便,但如果你要做的运算和元素在列表中的位置有关,比如把两个列表对应的项相加,这时就需要用第二种方法了。
字符串遍历
字符串本来就是一个字符序列,所以用for语句遍历是很方便的:
s = '今天天气不错啊'
for i in s:
print(i)
2、while循环
while 循环被称为“条件循环”,它适用于在某种条件下重复执行代码的场景。Scratch中有“重复执行…直到”,是当条件成立时就退出循环了,而while是“当……时执行”,意思是只要条件成立就一直循环下去。while语句的格式是:
while <判断条件>:
执行语句
由于while循环是否继续执行取决于条件,所以一般在循环体中,我们会修改条件,从而使条件失效时退出while循环。比如:
i = 1
s=0
while i <=100:
s += i
i +=1 # 千万不要漏写这一行
print(s)
运行这段程序,你会发现它和上面我们用for语句写的循环是一样的作用,都是求1+2+3+…+99+100的值。但是,千万不要忘记写i+=1,因为如果没有这一句,循环是否执行的判断条件就不会变,这个循环会一直执行下支,就类似于Scratch中的“重复执行”(无限循环),必须手动停止程序,才能让循环结束,你写的print(s)永远不会得到执行。
这样没有退出条件的无限循环又称为死循环
。其实,无限循环是有用的,还记得我们在编写Scratch程序时经常用“重复执行”来循环播放背景音乐吗?如果程序不停止,它会一直播放下去。另外,在一些游戏类的程序中,也会用到这种不断重复执行的场景,以后我们用到的时候再讲。但如果程序的无限循环不受你控制了,比如你就是结束程序它也不听话,这就成了”死循环“。所以,死循环就是失控的无限循环,是不符合程序初衷的无限循环。
最后强调一下while循环的条件,可以是关系表达式、逻辑表达式、算术表达式等,0、空字符串、空列表这类的值代表False,而非0数值、非空字符串、非空列表可以代表True。
比如你这么写:
# 注意,这是个死循环!
i = 0
while 1:
i += 1
print(i)
三、循环中止与跳过
在循环执行中可能有一种情况,就是想中途结束循环。比如上面的无限循环,如果我们想在i>100时就退出循环,应该怎么写呢?这时你可以使用break语句:
# 注意,这是个死循环!
i = 0
while 1:
i += 1
if i >100:
break
print(i)
在循环体中,我们加了一个if判断,如果i>100,使用break退出了循环。这是某些情况下退出循环的一种可选方法。
break是直接退出循环,我们还可以使用continue来退出“当前这一次”循环,什么意思呢?就是碰到有些情况下,不想执行这一次循环中下面的循环语句了,可以跳过,直接执行下一次。比如在上面输出英雄名字的代码中,碰到“赵云”时就跳过,我们可以这么写:
heros = ['关羽','黄忠','赵云','张飞','魏延']
for i in heros:
if i == '赵云':
continue
print(i)
这就像五个人排队打饭,到赵云的时候,厨师说:没你的,下一个!于是就把赵云跳过去了。
四、联合使用分支与循环
目前我们把分支和循环学完,就可以组合来写一些逻辑相对复杂的程序了。比如,我们以前学习的冒泡排序:
如果要翻译成Python代码,该怎么写呢?
arr = [7,4,5,2,1,3, 9,8,6]
for j in range(len(arr)):
swap = False
for i in range(len(arr)-1, j, -1):
if arr[i] < arr[i-1]:
arr[i], arr[i-1] = arr[i-1], arr[i] # 交换两个变量的值
swap = True
if not swap:
break
print(arr)
感觉是不是比Scratch更简短?确实,如果你掌握了Python语言,写起来要比Scratch更加方便快捷,你会觉得写代码比拖积木更快乐!
需要注意的是,在写嵌套层次比较多的代码时,一定要注意缩进,否则代码就乱套了。
五、课后作业
在列表1、列表2中分别存储着五个人的姓名和他们的身份证号:
- 列表1:[‘张三’,’李四’,’王五’,’赵六’,’孙七’]
- 列表2:[‘410305200801057425’, ‘410311198009065550’, ‘410301197611238426’, ‘410302199811257326’, ‘410308202102237214’]
请编写程序,根据每个人的身份证号,循环判断每个人是否到达法定结婚年龄。
注: – 法定结婚年龄的判断标准是:男性22岁,女性20岁。 – 身份证号码中的第17位数字是如果是奇数性别为男,偶数则为女。 – 身份证号中第7-14位代表出生年月日,可以用于计算年龄。
程序要按以下格式输出:
- 张三:XX岁,性别X,达到/未达到法定结婚年龄
- 李四:XX岁,性别X,达到/未达到法定结婚年龄
- ……