目录
2.1 布尔值
布尔值一共只有两个值:True、False。需要注意的是,布尔值只能以开头大写,后续小写的形式出现,并且不能作为变量名使用,例子见上图。图中输入true显示错误信息,因为python没有将true作为布尔值,而是作为一个变量名,所以错误信息中出现了“name ’true‘ is not defined”,表示true没有被定义。
2.2 比较操作符
(注:此处程序使用IDLE运行)
前一章也介绍过几个操作符,但是“+”号等符号属于数学操作符,而本节所介绍的属于关系操作符,是关于判断数据之间的关系的操作符,不能加入数学计算。
“==”和“!=”符号分别表示数据间相等和不相等,处于相反关系。此处注意到“==”号与上一章的赋值语句中的“=”号很相似,但是两者并不一样。“==”号用于判断,两个数据是否相等,意义是判断;而“=”号则是赋值,将右值放入左边的变量中,意义是定义,所以需要注意区分。根据图示,如果符合关系操作符判断,则输出True,反之,则输出False,结果都是用布尔值进行展示。下图同样使用的是这两个符号,但是对象变成了浮点数和字符串。
根据上图所示,“==”号和“!=”号在浮点数和字符串中同样适用。并且对布尔值进行关系判断,同样输出布尔值结果,即“真真得真,真假得假”。
图中这几个符号比较好理解,都是数学中得通用常见比大小符号,但是与前面的两个符号不同,这四个符号只用于整数型和浮点数。
2.3 布尔操作符
2.3.1 二元布尔操作符
and和or操作符被称为二元操作符,是因为这两个操作符一般只会接收两个布尔值(或表达式)。and和or操作符得输出结果与离散数学中的合取、析取很相似。对and操作符而言,只有两个布尔值都为True,输出结果才为True,反之就是False。对or操作符而言,只要有一个布尔值为True,则输出结果就为True。举例如下:
and和or操作符的真值表如下:
2.3.2 not操作符
not不同于二元布尔操作符,因为not只作用于一个布尔值。易知,not的意思就是相反的,即将布尔值取反。不在展示例子,直接给出真值表,如下:
2.4 混合布尔和比较操作符
既然已经介绍完布尔操作符和比较操作符,那么把两者结合起来会发生什么呢?
虽然数字不能和布尔操作符直接连接,因为布尔操作符只作用于二个布尔值,但是我们观察到比较操作符的输出结果为布尔值,因此可以等待比较操作符运行完后,对第一部分的结果进行布尔运算,最后得出答案。但是由于很多操作符结合到一个式子后,会出现运算顺序混乱,所以python对操作符进行了运算顺序规定:在所有算术和比较操作符求值后,先求not操作符,然后and操作符,最后or操作符。
2.5 控制流语句
2.5.1 if语句
最常见的控制流语句就是if语句,if语句具有四个组成部分:1.if关键字。2.条件(求值为True或False的表达式)。3.冒号。4.在下一行开始,缩进的代码块(if子句)。if语句可以理解为一个开关,若if关键词后的条件为True,那if子句就会执行,反之则不会执行。如下图:
图中代码就是最简单的if语句。先输入一个名字,进入if语句执行,若输入的是“dyy”,经过if语句执行后,就变成了True,程序识别True指令后,执行if子句,即输出“姓名正确!!!”。若输入的不是“dyy”,则会出现下图情况:
输入的是“dyy1”,即与if语句规定的“dyy”不同,输出False。程序识别到的是False指令,所以不会执行if子句内容,而是直接自动结束运行。 本程序的流程图如下:
2.5.2 else语句
else语句和if语句是关联的。if子句在if语句的条件的结果为True时执行,而else子句就是结果为False时执行,所以else语句是不含有条件的,它的条件就是if语句的相反。所以else语句的组成部分是:1.else关键词。2.冒号。3.else子句。例子在上一例的基础上添加如下:
输入“dyy1”,即与if语句规定的“dyy”不同,所以运行结果为False,不执行if子句,执行else子句,则最后输出“姓名不正确,重新输入!!!”。本程序的流程图如下:
2.5.3 elif语句
elif语句的位置和else语句相似,都是在if语句的后面,同时elif语句也可以跟在另一个elif语句后面。elif语句的意思是“否则如果”,即当if子句不执行是,才会执行elif子句。但是elif语句和else语句也不同,因为else语句是if语句的对立,没有条件这一要素,但是elif语句含有条件,即else和if的结合体,既不符合if语句的条件,又要符合elif的条件,才会执行elif子句。elif语句的组成为4个要素:1.elif关键字。2.条件(求值为True或False的表达式)。3.冒号。4.在下一行开始,随进的代码块(elif子句)。举例如下:
name = input()
age = int(input())
if name=='dyy':
print("姓名正确!!!")
elif age<18:
print("不符合,重新输入!!!")
此程序有四种运行结果,分别展示如下:
根据这四个运行图可知,只有图三完成运行了elif子句,图一和图二完成运行了if子句,图四没有输出。并且根据输入可知,“dyy”输入符合if要求,即执行if子句,后面程序将省略。“dyys”不符合if要求,即不执行if子句,然后进行elif条件的判断,判断age与18的大小关系,17小于18,19大于18,即17符合elif条件,所以只有图三执行elif子句,19不符合elif条件,所以图四不执行elif子句。
难度加大!!!
如果程序中加入多个elif语句,那会变得怎么样?
图中所示,定义name为Carol,age为3000。代入程序后,name不符合if语句条件, 不执行if子句,转到第一个elif语句,因为age为3000,3000>12,所以不符合第一个elif语句的条件,也不执行第一个elif子句,再转到第二个elif语句,3000>2000,符合第二个elif语句的条件,则执行第二个elif子句,即'Unlike you, Alice is not an undead, immortal vampire.',如图所示。因为已经符合了第二个elif语句的条件,所以第三个elif语句作废,不运行。本程序流程图如下:
根据流程图可以很轻松的看出,elif语句一个连着一个,如果其中一个为True,则后面的代码不运行,当前语句运行完后,直接到结束。
另外,elif语句的次序也很重要,如果不注意,将会导致输出结果完全不同。就以上面例子的变形为例,将其中两个elif语句的次序调换,如下图:
name = 'Carol'
age = 3000
if name == 'Alice':
print('Hi, Alice.')
elif age < 12:
print('You are not Alice, kiddo.')
elif age > 100:
print('You are not Alice, grannie.')
elif age > 2000:
print('Unlike you, Alice is not an undead, immortal vampire.')
可以发现,与上面的代码发生了一点变化:第二个elif语句和第三个elif语句的位置发生了互换,那么最后运行结果是否会和上面代码的结果一样呢?请看下图:
发现运行结果不一样了,为什么呢???
结合流程图分析:
程序将age>100放在了前面,那就说明程序将会先执行此代码块。age=3000,则3000>100,符合elif语句的条件,就会执行第二个elif子句,即'You are not Alice, grannie.'。因为第二个elif语句的条件已经被满足了,所以第三个elif语句被自动终止,不再运行,直接到结束命令,运行结束。所以此次运行结果不同与上一次,由此可得。因此,编写代码时,也要小心elif语句的次序!!!
最后,若将if语句,elif语句和else语句结合在一起呢?
name = 'Carol'
age = 3000
if name == 'Alice':
print('Hi, Alice.')
elif age < 12:
print('You are not Alice, kiddo.')
else:
print('You are neither Alice nor a little kid.')
这就很好理解了,结合之前的知识,若不符合if语句的条件,则会判断是否符合elif语句的条件,若还是不符合,则会执行else子句。根据理论分析,此程序运行结果应为'You are neither Alice nor a little kid.'。
而需要注意的是,根据elif定义,elif语句需要否定前面的条件后才能运行,所以所有的elif语句都应该跟在if语句后,因此不要将elif语句放在开头。
2.5.4 while循环语句
while语句在各大计算机语言中都含有,都表示循环运行。while语句的组成部分有:1.while关键字。2.条件(求值为True或False的表达式)。3.冒号。4.while子句。当while语句的条件为True时,就可以开始运行了。光看组成部分,感觉while语句和if语句很相似,但是两者完全不一样。从功能上来说,if语句在执行完后,会执行if子句,然后就结束了;但是对于while语句来说才刚刚开始,如果语句的条件一直恒定为True,那么while语句在执行完while子句后,会跳回while语句的开始,再次执行,一直这样运行,就会形成循环,甚至死循环。从流程图来看,如下图:
可以清楚看出两种语句的区别。在while语句中,可以看见一个循环的图形,而在if语句中没有。
2.5.5 break语句
前面说到了while语句可能会陷入死循环,那如何跳出循环呢?这就需要提到break语句和continue语句,此节先介绍break语句,continue语句将在下一节介绍。 break语句举例如下:
首先观察while语句,条件是True,说明一直为真,即循环会永久进行,出现死循环,但是本程序输出结果后,就结束了运行,为何?这时发现在原先的if子句后又多了一行代码,break语句。而break也正是终止了程序的死循环。break语句的出现,完成了本程序的两个优点:1.避免程序出现死循环。2.如果输入不符合if语句条件,可以循环进行输入,直到正确为止,保证功能的完备。就如下图:
本程序流程图如下:
2.5.6 continue语句
continue语句和break语句一样,都具有终止循环的功能,但是两者间有一点不同。break语句使用就会直接跳出循环,即不在while循环内部;而continue语句是在循环中进行中止,并返回循环的开始,例如有一个while循环程序,第一步要求输入姓名,第二步要求输入年龄,第三步要求输入就读学校并进行识别,若在学校中并没有查找到该姓名,就应该返回重新输入姓名和年龄信息。那么此处是不能使用break语句的,因为使用后,程序会直接跳出循环,并终止运行。所以continue语句就用在此处,可以让第三步之后的程序暂停运行,并返回循环开始处,重新开始循环,便可以完成这一要求。代码如下:
while True:
print("请输入姓名信息:")
name = input()
print("请输入年龄信息:")
age = int(input())
print("请输入就读学校:")
school = input()
if school == 'gdufs':
print("查有此人!")
break
else:
print("查无此人!请重新输入!")
continue
print("查询完毕!!!")
代码运行如下:
根据代码的运行结果可以发现,break语句和continue语句的区别就是终止运行的范围不同。break语句得范围是整个程序代码,而continue语句是循环函数内部。两者结合使用,可以达到一定的功能效果。该程序流程图如下:
(此程序尚不完善,存在逻辑问题,仅作为展示continue语句使用,切勿深究。)
2.5.7 for循环和range()函数
for循环语句同while语句一样,都具有循环执行代码得功能,但是for循环更加简便,因为for循环语句可以控制循环的次数,而不是像while语句一样,可能出现死循环。而for循环本身并不能控制次数,这就需要另外一个函数提供支持——range()函数。
for循环语句的基本形式:for i in range(5):,并且总是包含6个部分:1.for关键字。2.如 i 的变量名。3.in关键字。4.调用range()函数,最多传入3个参数。5.冒号。6.for子句。以书中例子说明:
print('My name is')
for i in range(5):
print('Jimmy Five Times (' + str(i) + ')')
range(5)表明数字从0-4,而非1-5,虽然都是五个数字,但是程序的序号标号一般从0开始。代码运行结果如下:
从程序运行结果可以看出,代码一共运行了五次,并且输出结果的数字是0-4,符合理论值。当i=4时,代码输出最后一个结果,而i+1=5,但是5已经超出了range(5)规定的次数范围,不执行代码,即中止运行,跳出循环,运行结束。同时,此代码也可以用while语句来实现,代码如下:
print('My name is')
i=0
while i<5:
print('Jimmy Five Times (' + str(i) + ')')
i=i+1
可见,从复杂程度看,for循环语句确实比while语句更胜一筹,所以在选用循环语句时,需要清楚要实现的功能适合哪种语句,再进行编写。
2.5.8 range()函数的说明
在上一节中,提到了range(5)这个数据。但是range函数根据定义可以传入3个参数。那如果range函数传入两个参数是什么情况呢?例下图:
for i in range(12, 16):
print(i)
range(a,b)中,a代表for循环变量开始的值,b代表上限。range(12,16),根据对range函数的初步认知可以发现,range(12,16)的运行结果是12-15,即 [ a,b)。所以这两行代码的运行结果是:
由于是循环语句一个一个输出,所以自带换行命令,出现四个数字四行的结果。range函数传入两个参数的情况解释完成,那三个参数呢?例下图:
for i in range(0, 10, 2):
print(i)
range函数传入三个参数比较复杂,引入一个新概念——步长。range(a,b,c)中,a代表起始值,b代表终止值,和两个参数一样,取值范围是 [ a,b),c代表步长,即间隔。图中range(0,10,2)意思是0-9,从0开始+2取值。运行结果如下:
另外,起始值、终止值和步长都可以取负数。例如range(3,-3,-1),那输出结果就是3,2,1,0,-1,-2。由此可见,for循环可以递增,也可以递减。
2.6 sys.exit()函数的介绍
sys.exit()也是程序终止函数,但是使用这个函数的前提是导入sys模块,但是它的使用率小,代码比break语句等麻烦很多,在这里不过多解释。举例:
import sys
while True:
print('Type exit to exit.')
response = input()
if response == 'exit':
sys.exit()
print('You typed ' + response + '.')
图中程序是一个死循环,如果想要结束程序,唯一的办法就是输入exit,调用sys.exit()函数,结束运行。
2.7 实践程序一(猜数字)
猜数字小程序代码如下:
import random
secretNumber = random.randint(1, 20)
print('I am thinking of a number between 1 and 20.')
for guessesTaken in range(1, 7):
print('Take a guess.')
guess = int(input())
if guess < secretNumber:
print('Your guess is too low.')
elif guess > secretNumber:
print('Your guess is too high.')
else:
break
if guess == secretNumber:
print('Good job! You guessed my number in ' + str(guessesTaken) + ' guesses!')
else:
print('Nope. The number I was thinking of was ' + str(secretNumber))
代码分析:先导入random模块,为了可以调用random.randint()函数进行随机生成数字的任务。并对生成数字做了1-20之间的范围约束。程序使用了for循环语句,此处循环的范围是1-6,即表示此循环最多可以进行6次。猜数字,要有提示大小,所以就设计了两个提示词,数字大和数字小,分别由if语句和elif语句的条件携带,最后加上else语句,即若都不符合大或小,就是相等,跳出循环,不输出提示语。跳出循环后,若输入数字与随机生成数字相同,则为成功;若6次都未成功猜出数字,则为失败,并揭晓最后数字。代码运行如下:
2.8 实践程序二(猜拳)
猜拳小程序代码如下:
import random, sys
print('ROCK, PAPER, SCISSORS')
wins = 0
losses = 0
ties = 0
while True:
print('%s Wins, %s Losses, %s Ties' % (wins, losses,ties))
while True:
print('Enter your move: (r)ock (p)aper (s)cissors or (q)uit')
playerMove = input()
if playerMove == 'q':
sys.exit()
if playerMove == 'r' or playerMove == 'p' or playerMove == 's':
break
print('Type one of r, p, s, or q.')
if playerMove == 'r':
print('ROCK versus...')
elif playerMove == 'p':
print('PAPER versus...')
elif playerMove == 's':
print('SCISSORS versus...')
randomNumber = random.randint(1, 3)
if randomNumber == 1:
computerMove = 'r'
print('ROCK')
elif randomNumber == 2:
computerMove = 'p'
print('PAPER')
elif randomNumber == 3:
computerMove = 's'
print('SCISSORS')
if playerMove == computerMove:
print('It is a tie!')
ties = ties + 1
elif playerMove == 'r' and computerMove == 's':
print('You win!')
wins = wins + 1
elif playerMove == 'p' and computerMove == 'r':
print('You win!')
wins = wins + 1
elif playerMove == 's' and computerMove == 'p':
print('You win!')
wins = wins + 1
elif playerMove == 'r' and computerMove == 'p':
print('You lose!')
losses = losses + 1
elif playerMove == 'p' and computerMove == 's':
print('You lose!')
losses = losses + 1
elif playerMove == 's' and computerMove == 'r':
print('You lose!')
losses = losses + 1
代码分析:首先,程序先导入了两个模块,random和sys模块。random模块方便于设计随机数,sys模块便于迅速退出程序,终止运行。然后就设计了三个变量,wins、losses、ties,方便记录玩家的胜负情况。第一步是玩家输入一个手势,用三个字母替代,或是q(退出)。如果玩家选择了q,则符合第一个if语句的条件,调用sys.exit()函数,直接退出程序。若是输入了r、p或s,则表示玩家开始游戏,执行第二个if子句,即break语句,跳出内部循环,来到外部循环。若是玩家填写的不是这四个字母,那么程序就会执行最好一句,并返回while语句开头,循环进行。第二步,进入到外部循环后,可以设计好三个字母的提示词,尽量美观和完整。然后程序调用random.randint()函数进行随机生成数字,在1-3之间,对应三种手势。第三步就是比较了,让玩家自己输入的手势于程序自动生成的手势比试,因为是三种手势,所以输赢情况只有6种加上平局,可以自行罗列情况,并编写代码。并根据输赢情况,对原先的三个记录变量进行加法。而外部循环while语句的条件是True,所以可以无限循环,输出输赢情况,进入下一次全新的过程。代码运行如下:
2.9 小结
本章主要介绍了控制流语句,布尔值及运算。break语句和continue语句在循环语句中也占据着重要的地位。通过加入模块,可以更好的调用其他类型函数,更好的完成要求。
2.10 课后习题选讲
2.10.1
答:False;False;True;False;False;True
2.10.2
答:3 个语句块是 if 语句中的全部内容,以及 print('bacon')和 print('ham')这两行:
print('eggs')
if spam > 5:
print('bacon')
else:
print('ham')
print('spam')
2.10.3
答:
if spam == 1:
print('Hello')
elif spam == 2:
print('Howdy')
else:
print('Greetings!')
2.10.4
答:break 语句将执行移出循环,接着执行循环之后的语句。continue 语句将执行移到循环的开始处。简而言之,break语句是将运行跳出循环,而continue语句还是在循环内。
2.10.5
答:
for循环语句:
for i in range(1, 11):
print(i)
while循环语句:
i = 1
while i <= 10:
print(i)
i = i + 1
(例如,2.5.7的for循环语句与while语句的相互转换,与此题意思相当。)