
1.3 流程控制
流程控制语句用来实现对程序流程的选择、循环和返回等进行控制。Python中主要的流程控制包括if(判断)、for(循环)、break(跳出)、continue(继续)等语句。
1.3.1 程序块与作用域
在大多数高级语言中,程序块与作用域有不同的概念。
· 程序块结构是一种程序结构形式,使程序变得清晰,便于阅读和修改。比如C、C++中允许程序员按照自己的习惯在不同的行之间采取任意对齐方式。
· 作用域是按变量或函数的可见性定义的程序子集。如果某个符号的名称在给定执行点是可见的,则称该符号在作用域内。比如在C、C++中用大括号“{ }”表达作用域。
而Python将两个概念进行了结合,用一种表达方式(即缩进)同时表达程序块和作用域的概念,即相同缩进范围内的代码在一个程序块和作用域中,且同一程序块和作用域中不能有不同的缩进。Python中用冒号“:”作为程序块标记关键字。比如,Python中可以有这样的代码:

上述代码在if块中分两行打印了两个单词,该块中的两条语句有相同的缩进。
下面的代码因为在if块中出现了两个不同缩进的语句行,所以不符合Python的语法规则(执行时Python解释器会报错):

注意:每个用冒号“:”标记的程序块内的代码必须有相同的缩进。
在C、C++、Java等语言中允许定义空作用域,即在作用域中不写任何代码,达到使作用域什么也不做的目的。由于在Python中使用缩进自动表示作用域,因此作用域中必须要写入一行以上的代码。Python中使用语句pass来定义作用域,但不执行任何动作。
【示例1-19】如下程序定义了if语句块,但不做任何操作:

技巧:pass语句用于“需要写代码,但实际什么也不做”的场合。
1.3.2 判断语句
条件判断是依据指定的变量或表达式的结果,决定后续运行的程序,最常用的是if-else指令,可以根据指定条件是否成立来决定后续的程序。也可以组合多个if-else指令进行较复杂的条件判断。
Python中的if 语句有如下3种语法形式。

或者

或者

【示例1-20】如下程序可演示if语句的使用方法:

这是一段根据控制台输入数字的参数判断数值大小的程序,对其解析如下。
· 定义了变量param的初始值为空(None),该变量用于在之后保存输入参数。
· 第1个if语句判断控制台是否有参数输入,如果有,则将第1个参数转换为int类型并放入param变量中。
· sys.argv是一个系统tuple变量,Python解释器在运行Python程序时将命令行参数传入sys.argv中。sys.argv中的第1个值(索引为0)是Python程序名,从第2个(索引为1)开始的其他元素为字符串类型的控制台输入参数。
· 表达式int(sys.argv[1]) 将第1个输入参数从字符串类型转换为整型。
· 第2个if语句是一个多条件判断语句:首先判断param变量是否被设置,如果没有被设置,则通过两条print语句输出警告;通过两个elif语句判断另外两个条件并进行输出;通过else执行默认语句。
技巧:每个if、elif、else块中可以放入多条语句。
将如上代码保存为if.py文件,在控制台中调用该程序的执行结果如下:


1.3.3 循环语句
在不少实际问题中有许多具有规律性的重复操作,因此在程序中需要重复执行某些语句,而能否继续重复则取决于循环的终止条件。循环结构是在一定条件下反复执行某段程序的流程结构,被反复执行的程序叫作循环体。循环语句由循环体及循环的终止条件两部分组成。Python中的循环语句有两种形式:while语句和for语句。
1.while语句
while语句的语法为:

其语意为:判断expression表达式,如果该表达式为真,则执行repeat_block并再次判断expression,直到expression返回假为止。
【示例1-21】while代码演示如下:

如上代码逐个输出myList列表中的内容,直到列表长度为0,即不满足条件len(myList) > 0为止。将其保存为文件while.py,执行结果如下:


注意:循环语句要防止死循环,如果while语句中的expression一直为真,则程序永远无法退出repeat_block的执行。
2.for语句
Python中的for语句类似于C#、Java中的foreach语句,语法为:

其中for/in是关键字,语意为:针对iterable中的每个元素执行repeat_block,在repeat_block中可以用element变量名来访问当前的元素。iterable可以是任意Sequence类型簇、集合或迭代器等。
【示例1-22】for代码演示如下:

如上代码逐个输出myList列表中的内容。将其保存为文件for.py,执行结果如下:

3.break及continue语句
开发逻辑较复杂的程序时,在while或for循环语句的循环体中有时需要提前结束循环,或者在本轮循环体尚未结束时提前开始下一轮循环,这就需要用到break及continue语句。
【示例1-23】break及continue语句代码演示如下:


上述代码一直提示让用户输入字符串“quit”,如果用户输入不正确则让用户再次输入,直到输入正确为止;并且每输错3次就提示用户“Please input quit!”。解析如下。
· 变量count用于对循环体计数,程序主体由while循环体构成。
· raw_input()函数获得客户端输入,raw_input的参数是提示用户输入的字符串。
· 用if语句判断输入是否正确,如果正确则用break语句退出循环。
· 用if语句判断本次输入是否是3的整数倍,如果不是则用continue语句继续循环。
将代码保存为break.py,程序运行结果如下:

技巧:raw_input()函数用于获取控制台输入。
1.3.4 语句嵌套
和其他高级语言一样,Python允许if、while、for等语句的嵌套使用。
【示例1-24】如下是用Python实现排序算法的代码:


在代码中实现了两层循环,在if语句的执行体中用到了交换运算符:

交换运算符可直接交换两个变量的内容,而无须用到中间变量。把代码保存为loop.py,执行结果如下:

技巧:用交换运算符可以直接交换变量的值。