每天10分钟,带你一周精通Python:第6章选择和判断
恭喜啊,你已经学习到最有意思的一章了。我希望到目前为止你都很享受这个专栏课程。在本章中,我们将学习一下如何让你的程序更加聪明,足够进行选择和判断。具体地说,我们将会学习 if语句、for循环和while循环语句。 它们被当作是控制流程工具,可以控制程序的流程。而且,我们也将学习try、except语句,它是用于确定在程序中出现错误时的处理方式。
然而,在深入这些控制流程工具之前,我们首先需要了解一下条件语句。
6.1 条件语句
所有的控制流程工具都需要判断一个条件语句。根据是否满足条件的情况,程序将会执行不同的内容。
最常见的条件语句是比较语句。如果想要比较两个变量是否一样,我们可以使用号(双=)。比如,如果你写下xy,你就是在让程序检查x的值是否与y的值一样。如果它们一样,条件就符合,语句的判断将为True。否则,语句的判断将为False。
其他的比较符号包括!=(不等于)、<(小于)、>(大于)、<=(小于等于)和>=(大于等于)。下面的表中展示了这些符号的使用方法,并给出了语句判断为True的例子。
不等于:
5 != 2
大于:
5>2
小于:
2<5
大于等于:
5>=2
5>=5
小于等于:
2 <= 5
2 <= 2
如果我们想要把多个条件连接起来,也有三个有用的逻辑符号:and、or 、not。
and符号在所有条件都满足时返回True。否则它将返回False。 比如,语句5==5 and 2>1将会返回True,因为两个条件都为True。
or符号在至少有一个条件满足时返回True。否则它将返回False。 语句5>2 or7>10or3==2将返回True,因为第一个条件5>2为True。
not符号在not关键字后面的条件为假时返回True。否则它将返回False。 语句not 2>5将返回True,因为2不大于5。
6.2 if语句
if语句是控制流程语句中最常用的语句之一。它让程序判断某个条件是否满足,并根据判断的结果执行对应的操作。if语句的结构形式如下所示。
if condition 1 is met:
do A
elif condition 2 is met:
do B
elif condition 3 is met:
do C
elif condition 4 is met:
do D
else:
do E
elif表示“else if”,而且你想要多少个elif都可以。
如果你以前使用其他的编程语言如C或者Java编程, 看到Python中在if、elif和else关键字的后面不需要括号(),你可能会有些吃惊。而且,Python也不需要大括号{}来表示if语句的开始和结束。对应的,Python使用缩进来表示语句的开始和结束。任何缩进的代码在被判断为真的情况下,都被认为是一段将被执行的代码。
要想完全理解if语句是怎么工作的,赶快打开IDLE,并输入下面的代码。
userInput =input('Enter 1 or 2: ')
if userInput ==''1'':
print ("Hello World")
print ("How are you?")
elif userInput == ''2'':
print ("Python Rocks!")
print ("I love Python")
else:
print ("You did not enter a valid
number")
这段程序首先提示用户使用input函数输入。输入的结果会以字符串的形式保存到userlnput变量中。
接下来的语句if userlnput=="1”:会比较userlnput变量的值与字符串“1”是否一样。如果存在userlnput中的值是“1”,程序将会一直执行缩进的所有语句,直到缩进结束。在本例中,它将会打印“Hello World”,后面跟着“How are you?”。
另外,如果存在userlnput中的值是“2”,程序将会打印出“Python Rocks”,后面跟着“I love Python”。
对于其他的所有值,程序将会打印出“You did not enter a validnumber”。
运行三次这个程序,每次运行时分别输入1、2和3。你将会得到下面的输出:
Enter 1 or 2: 1
Hello World
How are you?
Enter 1 or 2:2
Python Rocks!
I love Python
Enter 1 or 2: 3
You did not enter a valid number
6.3 内联
内联if语句是if语句的一个更简单的形式,当你需要执行一个简单的任务时,使用它会更加方便。它的语法是:
do Task A if condition is true else do Task B
比如:
num1 = 12 if myInt==10 else 13
这个语句在mylnt等于10的时候把12分配给num1(Task A)。否则它把13分配给num1 (Task B)。
另一个例子是:
print ("This is task A"if myInt == 10 else
"This is task B")
这段语句在mylnt等于10时会打印出“This is task A”(Task A)。否则它会打印出“This is task B”(Task B)。
6.4 for循环
接下来,让我们来看看for循环。for循环会重复执行一段代码,直到for语句的条件不再有效为止。
6.4.1通过迭代循环
在Python中,可迭代意味着可以内部循环的对象,比如一个字符串、列表或者元组。通过迭代进行循环的语法如下所示。
for a in iterable:
print (a)
[样例]
pets =['cats','dogs','rabbits',
'hamsters']
for myPets in pets:
print (myPets)
在上面的例子中,我们首先声明了列表pets,并给它赋值了“cats”。“dogs”、“rabbits”和“hamsters”成员。接下来的语句for myPets in pets:在pets列表上循环,并依次把列表中的成员分配给myPets变量。
程序第一次运行for循环时,它会把“cats”分配给myPets变量。接下来print(myPets)语句打印出值“cats”。程序运行for循环的第二遍,它会把“dogs”分配给myPets,并打印出值“dogs”。程序会在列表上持续循环,直至到达列表的尾部。
如果你运行程序,你将会得到:
cats
dogs
rabbits
hamsters
我们也可以显示出列表中成员的索引值。为了达到这个目的,我们可以使用enumerate()函数。
for index, myPets in enumerate(pets):
print (index, myPets)
这个会为我们输出:
0 cats
1 dogs
2 rabbits
3 hamsters
接下来的例子展示了如何在一个字符串上循环。
message ='Hello'
for i in message:
print (i)
输出为:
H
e
l
l
o
6.4.2 在一段数字上循环
为了在一段数字上循环,我们就需要用到内建的range()函数。range()函数生成一段数字的列表,其语法为range(start, end, step)。
如果没有输入start,生成的数字列表将以0开始。
注意:
这里需要记住的一个有用的提示是在Python中(以及大多数的编程语言
中),除非特意强调,我们总是从0开始的。
比如,列表和元组的索引都是从0开始的。
当为字符串使用format()方法时,参数的位置从0开始。
当使用range()函数时,如果start没有指定,生成的数字将会从0开始。
如果step没有指定,将会生成一个连续数字的列表,即step=1。end的值必须指定。然而,关于range()函数的一个诡异的情况是,指定的end值并不会出现在生成的列表中。
比如,range(5)将会生成列表[0, 1, 2, 3, 4]。
range(3,10)将会生成列表[3, 4, 5, 6, 7, 8, 9]。
range(4,10,2)将会生成列表[4, 6, 8]。
为了了解在一个for语句中怎么使用range()函数,可以试试下面的代码。
for i in range(5):
print (i)
你应该可以得到:
0
1
2
3
4
6.5 while循环
接下来我们将要学习的流程控制语句是while循环。正如其名一样,一个while循环在某个条件保持有效的情况下,会重复执行循环内的指令一个while语句的结构如下所示。
while condition is true:
do A
使用while循环的大部分时间里,我们首先需要为函数声明一个变量作为一个循环的计数器。 让我们把这个变量叫作counter。在while语句中的条件将会判断counter的值,着它是否小于(或者大于)某个特定的值。如果是,循环将会执行。让我们看一个样例程序。
counter = 5
while counter > 0:
print("Counter =",counter)
counter = counter -1
如果运行这个程序,你将会得到下面的输出:
Counter = 5
Counter = 4
Counter =3
Counter = 2
Counter = 1
乍一看,一个while语句看起来有个最简单的语法,应该是最易于使用的。然而,当使用while循环时需要格外小心无限循环的危险。注意在上面的程序中,我们有一行counter=counter-1?,这一行非常关键。它会把counter的值减 1,并把这个新值重新分配给counter,覆盖重写原有的值。
我们需要把counter的值减1,这样循环条件while counter>0最终将会判断为False。如果我们忘记这么做,循环将会无止尽地运行,从而导致出现一个无限循环。如果你想要体验一下,可以把counter=counter-1这一行删掉,并重新运行程序。程序将会一直打印counter=5直到你以某种方式关闭这个程序。如果你有一个大型程序,这可不是一个好的体验,因为你不知道哪段代码导致了这个无限循环。
6.6 break中断
当使用循环时,有时在满足某个条件时,你可能想要退出整个循环。为了达到这个目的,我们使用break关键字,运行下面的程序,看下它是怎么工作的。
j=0
for i in range(5):
j=j+2
print('i=',i,’,j=,j)
if j== 6:
break
你应该可以得到下面的输出。
i=0,j= 2
i=1,j=4
i=2,j=6
没有break关键字的话,程序应该从i=0循环到i=4,因为我们使用的函数是range(5)。然而有了break关键字,程序会在i=2时结束。这是因为当i=2时,的值达到6,break关键字会导致循环结束。
在上面的例子中,注意我们在一个for循环内使用了一个if语句。在编程中,“混合匹配”多个控制工具是很常见的,比如在一个if语句内部使用一个while循环,或者在一个while循环中使用一个for循环。这种情况被称作嵌套控制语句。
6.7 continue
另一个循环中有用的关键字是continue。当我们使用continue时,本次循环中在关键字后的程序将会在本次循环中被跳过。下面的一个例子可以解释得更加清楚。
j=0
for i in range(5):
j=j+2
print('\ni=',i,',j=',j)
if j== 6:
continue
print ('I will be skipped over if
j=6')
你将会得到下面的输出。
i=0,j=2
I will be skipped over if j=6
i=1,j=4
I will be skipped over if j=6
i=2,j=6
i=3,j=8
I will be skipped over if j=6
i=4,j= 10
I will be skipped over if j=6
当=6时,continue关键字后的那一行将不会被打印。除了这个,其他的将会正常运行。
6.8 Try, Except
我们将要学习的最后的控制语句是try、except语句。这个语句在错误发生时可以控制程序执行的方式。语法如下:
try:
do something
except:
do something else when an error occurs
比如,尝试运行下面的程序:
try:
answer =12/0
print (answer)
except:
print (“An error occurred”)
当运行这个程序时,你将会得到“An error occured”这个信息。这是因为当程序尝试执行try语句块中的answer=12/0语句时,会出现一个错误,因为你不能用0去除一个数。trv代码块的剩余代码将会被忽略,而except代码块中的语句将会执行。
如果想要为用户根据错误类型打印出更多具体的错误信息,你可以在except关键字后指定错误的类型。尝试运行下面的程序。
try:
userInput1=int(input("Please enter a
number:"))
userInput2 = int(input("Please enter
another number:"))
answer =userInput1/userInput2
print ("The answer is ",answer)
myFile = open("missing.txt",‘r')
except ValueError:
print ("Error: You did not enter a
number")
except ZeroDivisionError:
print ("Error: Cannot divide by zero")
except Exception as e:
print ("Unknown error:",e)
下面的列表展示了不同用户输入将会得到的不同输出。>>>表示用户输入. =>表示输出。
>>> Please enter a number:m
=> Error: You did not enter a number
原因:用户输入一个字符串,但不能被转换为整数。这是一个ValueError错误。因此,在exceptValueError代码块中的语句将会被打印出来。
>>> Please enter a number:12
>>> Please enter another number:0
=> Error: Cannot divide by zero
原因:userlnput2=0。因为我们无法用0去除一个数,这是一个ZeroDivisionError错误。在except ZeroDivisionError代码块中的语句将会被打印出来。
>>> Please enter a number:12
>>> Please enter another number:3
=> The answer is 4.0
=> Unknown error: [Errno 2] No such file
or directory: 'missing.txt'
原因:用户输入可接受的值,print(“The answer is”,answer)这行代码正确执行。然而,下面的那一行会抛出一个错误,因为没有找到missing.txt这个文件。因此这不是一个ValueError错误或者ZeroDivisionError错误,最后的except代码块会被执行。
ValueError错误和ZeroDivisionError错误是Python中许多预先定义的错误类型中的两种。当函数的内建操作接收到一个参数,这个参数有正确的类型,但却有一个不合适的值时,ValueError错误就会被抛出。当程序试图用零除时, ZeroDivisionError错误将会被抛出。在Python中其他常见的错误包括:
IOError:
当一个I/0操作(比如内建的open()函数)因为一个I/O相关的原因失败时会被抛出,比如,“file not found”。
ImportError:
当一个import语句在寻找模块定义失败时被抛出。
IndexError:
当一个序列(比如,字符串、列表、元组)的索引超出范围时被抛出。
KeyError:
当无法找到一个字典中的关键字时被抛出。
NameError:
当无法找到一个局部或者全局变量时被抛出。
TypeError:
当一个操作或者函数应用到一个不匹配的类型对象时被抛出。
对于Python中的完整的错误类型的列表,可以参考https://docs.python.org/3/ library/exceptions.html。
Python对于不同类型的错误也预先定义了错误的信息。如果想要显示这些信息,你可以在错误类型后面使用as关键字。比如,为了显示默认的ValueError信息,可以这么写:
except ValueError as e:
print (e)
e是分配给错误的变量名字。你可以把它命名为其他的名字,但常见的用法是使用e来表示。我们程序中的最后一个except语句:
except Exception as e:
print ("Unknown error:",e)
就是使用预先定义错误信息的一个例子。它的作用是最后尝试捕获其他任意异常为指定的错误。