控制结构——循环语句与布尔表达式222for循环:回顾•语法forvarinsequence:body•语义:循环标志变量var取遍序列sequence中的每个值;对var所取的每个值执行一遍循环体body.编程实例:求平均值•需求:输入若干个数,求平均值.•显然可用熟悉的累积器算法模式•算法:输入数值个数n初始化累积变量sum=0循环n次输入数值x累加到sum输出平均值sum/n•用Python实现:avg1.py3编程实例:求平均值-average1#average1.py#Aprogramtoaverageasetofnumbers#Illustratescountedloopwithaccumulatordefmain():n=input(Howmanynumbersdoyouhave?)sum=0.0foriinrange(n):x=input(Enteranumber)sum=sum+xprint\nTheaverageofthenumbersis,sum/nmain()•注意:sum初值0.0,这样sum/n才是float类型!55while循环•avg1.py的缺点:需要用户输入n–不适合事先不知道n的场合•不知道n则不能用确定的计数循环for语句•不确定的条件循环:while–语法whilecondition:body–语义:只要条件成立就反复执行循环体;当条件不成立则执行下一条语句.666while循环的特点•循环前测试条件–若不满足,则循环体一次都不执行•循环体影响下一次条件测试–否则导致无穷循环–例如:for循环改写成while循环i=0whilei10:printii=i+1•若忘了最后一条语句会怎样?条件循环体yesno常见循环模式:交互循环•用户根据需要来循环执行程序某一部分•例如:avg2.py–不输入n,由程序自己数输入的值的个数–设置一个是否继续循环的标志初始化sum=0初始化count=0初始化moredata=yeswhilemoredata==yes:输入数据x累积sum=sum+x累积count=count+1询问用户moredata?输出平均值sum/count7常见循环模式:交互循环#average2.py#Aprogramtoaverageasetofnumbers#Illustratesinteractiveloopwithtwoaccumulatorsdefmain():sum=0.0count=0moredata=yeswhilemoredata[0]==y:x=input(Enteranumber)sum=sum+xcount=count+1moredata=raw_input(Doyouhavemorenumbers(yesorno)?)print\nTheaverageofthenumbersis,sum/countmain()常见循环模式:哨兵循环•avg2.py不断要用户输入moredata,烦!•改进:设置一个特殊数据值(称为哨兵)作为终止循环的信号.–对哨兵唯一的要求就是能与普通数据区分•模式:输入第一个数据while该数据不是哨兵:处理该数据输入下一个数据•程序:avg3.py(负数哨兵),avg4.py(空串哨兵)9常见循环模式:哨兵循环-负数哨兵#average3.py#Aprogramtoaverageasetofnumbers#Illustratessentinelloopusingnegativeinputassentineldefmain():sum=0.0count=0x=input(Enteranumber(negativetoquit))whilex=0:sum=sum+xcount=count+1x=input(Enteranumber(negativetoquit))print\nTheaverageofthenumbersis,sum/countmain()常见循环模式:哨兵循环-空串哨兵#average4.py#Aprogramtoaverageasetofnumbers#Illustratessentinelloopusingemptystringassentineldefmain():sum=0.0count=0xStr=raw_input(Enteranumber(Entertoquit))whilexStr!=:x=eval(xStr)sum=sum+xcount=count+1xStr=raw_input(Enteranumber(Entertoquit))print\nTheaverageofthenumbersis,sum/countmain()常见循环模式:文件循环•Avg1-avg4都是交互式输入数据的–不便处理大数据量.–一个输入错误即导致需要重新运行程序.•改进:建立一个数据文件.–数据处理应用中广泛使用•模式:打开数据文件fforlineinf.readlines():处理每个数据•编程实例:avg5.py12常见循环模式:文件循环-average5#average5.py#Computestheaverageofnumberslistedinafile.defmain():fileName=raw_input(Whatfilearethenumbersin?)infile=open(fileName,'r')sum=0.0count=0forlineininfile:sum=sum+eval(line)count=count+1print\nTheaverageofthenumbersis,sum/countmain()Average5执行结果•Nums.dat:34230-25-34.422.7•Whatfilearethenumbersin?nums.datTheaverageofthenumbersis3.38333333333常见循环模式:EOF哨兵循环•一次性读入–readlines()一次性把文件的所有行都读入–但内存有限!对大文件不合适.•分批读入–readline()每次读入一行–需要哨兵(如:空行),标志文件结束(EOF)line=f.readline()whileline!=“”:处理该行line=f.readline()–编程实例:avg6.py15常见循环模式:EOF哨兵循环-average6#average6.py#Computestheaverageofnumberslistedinafile.defmain():fileName=raw_input(Whatfilearethenumbersin?)infile=open(fileName,'r')sum=0.0count=0line=infile.readline()whileline!=:sum=sum+eval(line)count=count+1line=infile.readline()print\nTheaverageofthenumbersis,sum/countmain()常见循环模式:嵌套循环•嵌套循环:一个循环语句的循环体内有另一个循环语句.•用途:遍历一维空间只需一个循环变量,遍历二维空间需要两个循环变量,……,遍历n维空间需要n个循环变量.•例如:假设数据文件的每一行有多个数据.•编程实例:avg7.py–顶层循环仍如avg6.py–但每次顶层循环内,需要另一个循环来处理该行上的多个数据17常见循环模式:嵌套循环-average7#average7.py#Computestheaverageofnumberslistedinafile.#Workswithmultiplenumbersonaline.importstringdefmain():fileName=raw_input(Whatfilearethenumbersin?)infile=open(fileName,'r')sum=0.0count=0line=infile.readline()whileline!=:#updatesumandcountforvaluesinlineforxStrinstring.split(line,,):sum=sum+eval(xStr)count=count+1line=infile.readline()print\nTheaverageofthenumbersis,sum/countmain()Average7运行结果•Nums3.dat23,45,5678,89,10020,60,90•Whatfilearethenumbersin?nums3.datTheaverageofthenumbersis62.3333333333布尔值计算•布尔表达式:以真假为值•简单布尔表达式:exprrelopexpr•复杂布尔表达式:由多个布尔运算符组成的布尔表达式构成–布尔运算:and,or,not布尔exprand布尔expr(逻辑与)布尔expror布尔expr(逻辑或)not布尔expr(逻辑非)202121and的定义•And表示“并且”:–口诀:全1为1,有0为0–PandQ为真,ifP和Q都为真–用真值表表示更直观.PQPandQFFFFTFTFFTTT2222or的定义•Or表示“或者”:–口诀:全0为0,有1为1–PorQ为假,ifP和Q都为假•日常用语中的“或”往往具有互斥的涵义,即二选一.与此处的or不全相同!PQPorQFFFFTTTFTTTT2323not的定义•not表示“否定”:notP为真,ifP为假.PnotPTFFT布尔运算符的优先级•not最高,and次之,or最低–小测验:aornotbandc何意?–最好使用括号!24例:判断两点是否位置相同•嵌套if-elseifp1.getX()==p2.getX():ifp1.getY()==p2.getY():#pointsarethesameelse:#pointsaredifferentelse:#pointsaredifferent•用布尔运算符ifp1.getX()==p2.getX()andp1.getY()==p2.getY():#pointsarethesameelse:#pointsaredifferent25例:模拟racquetball的结束•先得15分者胜whilenot(scoreA==15orscoreB==15):#continueplaying•先得15分或7:0者胜a==15orb==15or(a==7andb==0)or(b==7anda==0)•至少要多2分才胜(a=15anda-b=2)or(b=15andb-a=2)或(a=15orb=15)andabs(a-b)=226布尔代数•布尔运算遵循的代数定律aandfalse==falseaandtrue==aaorfalse==aaortrue==trueaor(bandc)==(aorb)and(aorc)aand(borc)==(aandb)or(aandc)not(nota)==aDeMorgan’slawsnot(aorb)==(nota)and(notb)not(aandb)==(nota)or(notb)2728布尔代数•and具有类似乘法的属性•Or具有类似加法的属性•0and1分别对应falseandtrue。AlgebraBooleanalgebraa*0=0aandfalse==falsea*1=aaandtrue==aa+0=aaorfalse==a利用布尔代数简化条件•例如:racquetball结束条件whilenot(scoreA==15orscoreB==15):#continueplayingwhile(notscoreA==15)and(notscoreB==15):#continueplayi