3.控制流

一、前言

上一章,我们大概了解了一下python中的所有数据类型,但作为一门编程语言,这还远远不够。

1966年,计算机科学家 BohmJacopini 证明了这样的事实:任何简单或复杂的算法都可以由顺序结构选择结构循环结构这三种基本结构组合而成。

也就是说,想要真正能够编写程序,这三种基本结构是必不可少的。

这也就是本章的标题“控制流”,意为控制整个程序的运行流程。

二、顺序结构

顺序结构是最简单的,正如其名字的含义:顺序执行

而大部分编程语言,包括python,默认就是顺序执行的,比如下面这段代码:

print("1111")
print("2222")
print("3333")

其执行顺序就是从上到下开始执行的,这可以从它的打印结果中看出来:

1111
2222
3333

三、选择结构

顺序结构的一大难点在于,无法进行选择执行,比如当一个数字大于0,我就打印它大于0,否则就打印它小于等于0。

如果使用顺序结构,除非修改代码,否则它必然会执行所有的代码:

a=10
print("a>0")
print("a<=0")

这时候就需要选择结构了,所谓选择,就是看情况来执行某一段代码,或者不执行某一段代码。

python中的选择结构如下所示:

a=10
if a>0:
    print("a>0")

if a<=0:
    print("a<=0")

如果a大于0,就打印a>0,如果a小于等于0,就输出a<=0

用到的关键字为if,意思就是“如果”。

在它的后面紧跟一个判断语句就行了,这和数学中的概念是一致的,应该不用多说。

只是需要注意一下大于等于小于等于不等于以及等于的写法:

a=10 #一个=为赋值的意思
a==10 #两个=才是判断是否等于
a<=10 #小于等于是用<与=两个符号组合的
a>=10 #大于等于是用>与=两个符号组合的
a!=10 #不等于是用!与=两个符号组合的

判断完成后,需要在其后面添加一个:符号,代表后面跟着的语句就是当前面的判断语句为真时,要执行的语句。

注意这里的写法:

if a>0:
    print("a>0")

需要当前面if语句为真时才执行的语句,必须要在前面打上一个tab键(一般一个tab表示4个空格),也称缩进,python解释器就是通过缩进来识别语句所属块的。

比如像上面那样写,就代表后面的那个print语句属于前面的if语句,只有if后面的判断为真,才会执行它

如果有多条语句,那么每条语句都要有相同的缩进:

a=10
if a==10:
    print("1前面有缩进,属于上方的if语句块")
    print("2前面有缩进,属于上方的if语句块")
print("3前面没有缩进,不属于上方的if语句块")

就我个人而言,并不太认可使用“缩进”的方式规范代码块,毕竟这样写,如果代码量一多,实际上并不利于观察,但这是python语言的语法规定,只能适应了。

其它语言一般采用的都是{}的方式,将属于自己的代码用大括号包起来,个人觉得观察起来更加方便。

但你会发现,一个数要么大于0,要么就小于等0,这种只存在两面性的条件,如果要用if语句判断两次就太麻烦了。

所以我们可以通过else关键字来代替其它情况:

a=10
if a>0:
    print("a>0")
else:
    print("a<=0")

注意else不能单独出现,因为它的意思就是除此之外,即上面这段代码的意思就是:如果a大于0,则输出a>0,否则,就输出a<=0

同时注意,else关键字后面同样也是用的:,然后属于它的代码也需要前面有缩进才行。

在只有正反两面的情况下,上面的语句可以很好的工作,可一旦出现了多种情况,就不行了。

比如现在我想要判断负数0-10,以及大于10的数,这三种情况。

if else只能判断两种情况的条件,一旦出现了多个,如果发现要用上面的if语句,你就得写三条if语句

a=10
if a<0:
    print("a<0")
if a>=0 and a<10:
    print("a>=0 and a<10")
if a>=10:
    print("a>=0")

注意第二条语句,由于要在010之间,所以需要判断两次,由于前后执行的结果都是布尔类型,所以就可以用到上一章提到的and

也就是只有前后两个条件都为True,它的整个结果才为True,进而才会执行这条if后面的语句。

当然,由于python语言过于高级,你完全可以这样写:

if 0<= a <10:
    print("a>=0 and a<10")

这就和数学里面的表示方法差不多了。

观察上面的这种形式,还是觉得有点不优雅,毕竟这三个条件是同一个变量上的三种划分,这样写成三条if语句,就不容易看不出来三个条件的关联性了。

这个时候,我们就可以使用elif语句了:

a=10
if a<0:
    print("a<0")
elif 0<= a <10:
    print("a>=0 and a<10")
else:
    print("a>=10")

它的意义就在于,如果不满足第一个if语句,那我就继续判断elif后面的条件,如果还不满足,那才执行else后面的代码。

elifelse if的缩写,同样也是个判断语句,后面紧跟判断条件与:,以及要执行的代码块。

它与if不同之处在于,它只能跟在if后面,用来判断更多的条件。并且可以添加多个

发现了没,如果你用三条if语句,那就无论如何都要判断三次,而如果采用if elif else语句,只要前面某个条件满足了,后面的判断就不会执行了,进而就提升了程序的运行效率。

同时最后,还可以添加else语句,用来判断其它情况。

比如下面这段代码:

a=10
if a<0:
    print("a<0")
elif 0<= a <10:
    print("a>=0 and a<10")
elif 10<=a<20:
    print("a>=10 and a<20")
else:
    print("a>=20")

应该能看懂上面的代码吧?

除了上面这一种选择结构外,自3.10版本之后,python还支持match匹配模式进行选择,它更加强大,但鉴于其目前还处于早期,并且这是基础章节,就留到以后再讲了。

所以在python中,只要你需要进行判断的地方,选择if语句就对了。

四、循环结构

循环结构的作用就在于,它可以重复执行一段固定、或者有规律的代码,进而提升我们码代码的效率。

比如现在我想要输出五个“hello world”,如果没有循环语句,那我们就不得不写五次:

print("hello world")
print("hello world")
print("hello world")
print("hello world")
print("hello world")

虽然复制粘贴很容易,但程序中出现大量的重复代码,会使得维护成本大大提高。

比如,现在我不想要输出hello world了,我想要输出hello python,那你可能就不得不修改这五处地方才行。

还有如果我还想要每打印一次,同时还要其后面跟上它是第几句的话,那就更加麻烦了:

print("hello python1")
print("hello python2")
print("hello python3")
print("hello python4")
print("hello python5")

为了解决上面罗列的这些麻烦,就出现了循环结构。

python中一共只有两种循环:forwhile

我们首先来看比较简单的while循环:

a=5
while a!=0:
    print("hello python")
    a=a-1

同样是输出五次相同的字符串,但这次我们却只需要写print一次就行了!

上面这段代码,确实与上面介绍的if有点像,while后面跟着的同样是一个布尔表达式,只要这个表达式为True,那就不断执行后面紧跟着的语句,同样的,它后面也是用:来标识。

而属于它的代码片段,前面同样需要一个tab(4个空格)来标注。

这段代码的执行逻辑是:

  • 让a等于5
  • 判断a是否等于0,如果不等于0,就执行属于它的代码块
  • 如果不等于0,那就执行一次printa减一
  • 执行完成后,再返回判断现在a是否为0,如果仍然不为0,那就重复刚才的步骤,如果为0,那就执行结束,继续向下走执行其它语句。
  • 由于这里没有其它语句,所以程序就执行结束了。

如果想要无限循环打印,知道怎么写吗?

while True:
    print("hello python")

直接让布尔表达式恒等于True即可,此时程序将永远不会执行结束,只能强制中断它,你可以按终端按快捷键Ctrl+C实现强制终止程序执行。

循环语句非常的有用,比如我现在想要打印0-100中的奇数,亲手写print将其打印出来显然有些不可能。

所以这时候就可以用循环语句:

a=0
while a<100:
    if a%2==1:
        print(a)
    a=a+1

当然,这还需要结合前面提到的if语句

注意:这里的print前面有两个tab的空格距离,因为它属于if,所以需要比if多一个tab,但由于if又属于while中,if自己的前面就需要一个tab,所以综合下来它就是两个tab的距离,而后面的a=a+1,由于它属于while,而不属于if,所以只有一个tab的距离,如果不属于while语句的,那其前面就没有tab

%是求余运算符,比如 10%2=5.....0,所以结果为011%2=5....1,余数为1,说明它就是奇数。

当然,除了上面的那种用法外,我们在循环中还有两个经常用到的关键字:breakcontinue

break就是停止循环,比如下面的代码:

a=0
while a<100:
    if a%2==1:
        print(a)
    if a==50:
        break
    a=a+1

我在上面的循环中又添加了一个判断语句,如果a等于50了,那我就跳出循环,也就是不继续在这里执行了。

效果就是,只输出0-50的奇数,

相比于break这种直接跳出循环的粗暴操作,continue就要好一些,它只跳过当前的语句:

a=0
while a<100:
    a=a+1
    if a%2==0:
        continue
    print(a)

比如我将代码改写成为了上面这样。同样是输出0-100中的所有奇数。

但不同之处就在于,这里的判断语句是,如果它为偶数,那我就continue,即跳过当前这次循环,不再执行后面的语句,然后直接来到下一次循环

代码的语义就从原来的:如果这个数是奇数,那我就打印它,变成为,如果这个数是偶数,那我就跳过它,否则,我才打印它。

这两个关键字在循环中是非常常见的,以后你也会经常看到。

除却while循环外,使用频率更高的可能还是for循环,比如上面的代码,用for循环写的话,就会更加的简洁

for i in range(0,100):
    if i%2==1:
        print(i)

它主要有两个关键字:forin

简单来就是,for后面的i这个变量,要遍历in后面的这个范围。

这里用到的python中的range函数产生的一个0到100的范围,用来给i进行遍历。

后面章节聊到函数时,会再给大家详细讲解python中的一些常用函数以及作用

这样做,我们就无需每次都要判断是否大于0之类的事情,因为范围已经由in后面的range函数确定了。

最后同样是用:进行分隔,属于它的代码,前面同样要有一个tab键的空格。

至于里面的代码,与上面的一致,就不再讲解了。

这么看起来你可能觉得它也没什么特殊之处。所以下面我们来尝试遍历一个数组试一试:

arr=['111','2222','333','444','555']
i=0
while i<len(arr):
    print(arr[i])
    i=i+1

上面是用while语句写的代码,用到了python中的len函数,它的作用就像它的名字,就是用来求取长度的,这里求取的就是这个数组的长度

最后通过变量i,对其进行遍历,可以发现非常麻烦,但如果用for循环,就极其简单:

arr=['111','2222','333','444','555']
for i in arr:
    print(i)

这里的i就是数组中的每个元素,直接就可以取出来,而不用像上面的while循环那样,还需要用一个数字,通过数组下标才能进行遍历出其内部的元素。

作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux