python程序設計 課件 第4章 循環(huán)與輸出_第1頁
python程序設計 課件 第4章 循環(huán)與輸出_第2頁
python程序設計 課件 第4章 循環(huán)與輸出_第3頁
python程序設計 課件 第4章 循環(huán)與輸出_第4頁
python程序設計 課件 第4章 循環(huán)與輸出_第5頁
已閱讀5頁,還剩82頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

第4章循環(huán)結構與print語句Python程序設計第4章循環(huán)結構與print語句之前的程序代碼執(zhí)行時,都是一行接著一行,直到最后。但有時我們想重復執(zhí)行同樣的程序代碼,此時便需要用到循環(huán)(loop),程序員用循環(huán)連續(xù)多次執(zhí)行一系列語句。Python的for循環(huán)是循環(huán)遍歷序列的有限循環(huán);while語句是一個不定循環(huán),只要循環(huán)條件保持為真,它就繼續(xù)迭代。使用不定循環(huán)時,必須注意不要寫成無限循環(huán)。for循環(huán)語句1常見循環(huán)模式4while循環(huán)語句2break語句與continue語句3print語句5目錄4.1

for循環(huán)語句解析for循環(huán)程序?qū)嵗河嬎阋幌盗袛?shù)字的平均值程序?qū)嵗和顿Y的終值4.1for循環(huán)語句最簡單的循環(huán)稱為“確定循環(huán)”,也就是說,在循環(huán)開始時,Python就知道循環(huán)(又稱“迭代”)的次數(shù)。Python的for語句是一個循環(huán)遍歷一系列值的確定循環(huán)。Python的for循環(huán)語句的一般形式是:for<變量>in<序列>:<循環(huán)體><循環(huán)體>可以是任意Python語句序列,其范圍通過它在循環(huán)頭(for<變量>in<序列>:)下面的縮進來表示。4.1.1解析for循環(huán)關鍵字for后面的<變量>稱為“循環(huán)索引”,它依次取<序列>中的每個值,并針對每個值都執(zhí)行一次循環(huán)體中的語句。通常,<序列>部分由值“列表”構成。列表是Python中一個非常重要的概念,可以在方括號中放置一系列表達式,從而創(chuàng)建一個簡單的列表。見下列交互示例:>>>foriin[0,1,2,3]:print(i)0123>>>foroddin[1,3,5,7,9]:print(odd*odd)192549814.1.1解析for循環(huán)4.1.1解析for循環(huán)這兩個例子依次使用列表中的每個值執(zhí)行循環(huán)體。列表的長度決定了循環(huán)執(zhí)行的次數(shù)。在第一個例子中,列表包含4個值,即0至3,并且簡單地打印了這些連續(xù)的i值。在第二個例子中,odd取前5個奇數(shù)的值,循環(huán)體打印了這些數(shù)字的平方。我們再看看下面這個循環(huán)頭: foriinrange(10):將它與for循環(huán)的模板進行比較可以看出,range(10)必定是某種序列。4.1.1解析for循環(huán)事實上,range是一個內(nèi)置的Python函數(shù),用于“當場”生成一個數(shù)字序列,你可以認為它是一種數(shù)字序列的隱性描述。要明白range實際上做了什么,我們可以要求Python用另一個內(nèi)置函數(shù)list,將range轉(zhuǎn)換為一個簡單的舊式列表:>>>list(range(10)) #將range(10)轉(zhuǎn)換為顯式列表[0,1,2,3,4,5,6,7,8,9]可見,表達式range(10)產(chǎn)生數(shù)字0到9的序列。使用range(10)的循環(huán)等價于使用那些具體數(shù)字列表的循環(huán)。 foriin[0,1,2,3,4,5,6,7,8,9]:4.1.1解析for循環(huán)一般來說,range(<表達式>)將產(chǎn)生一個數(shù)字序列,從0開始,但不包括<表達式>的值,<表達式>的值確定了結果序列中的項數(shù)。這種“計數(shù)循環(huán)”模式是使用確定循環(huán)的一種很常見的方式。如果你希望在程序中做一定次數(shù)的某些事,可用一個帶有合適range的for循環(huán),即: for<變量>inrange(<表達式>):表達式的值確定了循環(huán)執(zhí)行的次數(shù),程序員經(jīng)常使用i或j作為計數(shù)循環(huán)的循環(huán)索引變量,只要確保所使用的標識符沒有用于任何其他目的。循環(huán)的有用之處在于其改變了程序“控制流”的方式。通常我們認為計算機是嚴格按順序執(zhí)行一系列指令。引入循環(huán)會導致Python退回去并重復執(zhí)行一些語句。類似for循環(huán)的語句稱為“控制結構”,因為它們控制了程序其他部分的執(zhí)行順序。4.1.1解析for循環(huán)用“流程圖”的圖形方式可以幫助我們來思考控制結構。流程圖用一些框來表示程序的不同部分,并用框之間的箭頭表示程序運行時的事件序列。右圖用流程圖描述了for循環(huán)的語義。

for循環(huán)的流程圖4.1.1解析for循環(huán)流程圖中的菱形框表示程序中的判斷。當Python遇到循環(huán)頭時,它檢查序列中是否有項。如果答案為“是”,則循環(huán)索引變量被賦予序列中的下一項,然后執(zhí)行循環(huán)體。一旦循環(huán)體完成,程序返回到循環(huán)頭并檢查序列中的下一個值。如果沒有更多的項,循環(huán)就退出,程序移動到循環(huán)之后的語句?!境绦?qū)嵗?-1】以for循環(huán)計算總分與平均成績。#for_score.pyscores=[60,73,81,95,34]n=0total=0forxinscores: #循環(huán)頭

n+=1 #循環(huán)體

total+=x #循環(huán)體avg=total/n請記錄:閱讀代碼,分析avg的運行結果為_______________________。4.1.1解析for循環(huán)4.1.1解析for循環(huán)其中最重要的是for循環(huán)頭“forxinscores:”,在“in”前面是你取的名稱,在“in”后面則是能夠提供一連串對象的對象,此例子中使用list對象,而for循環(huán)就會在每一輪依序逐一取出該list對象里的元素(對象),賦值給“in”前的名稱,以此例而言,首輪的x會是60,下一輪時x會是73,依此類推,直到用盡,到時便會跳出for循環(huán)。此例中循環(huán)結束后,n會是列表scores的長度(含有幾個元素),而total會是所有元素(成績)的總和,然后以“avg=total/n”算出平均成績。Python的for循環(huán)不僅能處理list,也可以處理tuple與str。4.1.1解析for循環(huán)下面的例子用來統(tǒng)計字符串內(nèi)有幾個字母'e':s='HelloPython'e_count=0forxins: #x會是字符串s里的每一個字母

ifx=='e':e_count+=1 #統(tǒng)計出現(xiàn)'e'的次數(shù)4.1.1解析for循環(huán)for循環(huán)的“in”其實跟賦值語句“=”的作用差不多,就是建立名稱與對象的綁定關系,還記得“a,b=0,1”這樣的賦值語句嗎?for循環(huán)也辦得到,例如,找出兩個成績都超過90分的學生:names_scores=(('Amy',82,90),('John',33,64),('Zoe',91,94))highs=[]forx,y,zinnames_scores:ify>=90andz>=90:highs+=[x,y,z]4.1.1解析for循環(huán)上述循環(huán)執(zhí)行時,首輪的x是'Amy'、y是82、z是90,依此類推。因為for循環(huán)的“in”幾乎等同于賦值“=”,所以也能使用“星號序列賦值”。例如,若把上述程序代碼的循環(huán)頭改成:forx,*yinnames_scores:...省略...那么首輪的x是'Amy',y是[82,90],依此類推。for循環(huán)的“in”后面不僅能放入list、tuple、str,也可以放入任何序列(sequence)類型與可迭代者(iterable)。序列和可迭代者是Python非常重要的類型,在第5章將會深入介紹?!境绦?qū)嵗?-2】兩重循環(huán),可得到所有顏色與動物的組合。#for_nested.pycolors=['red','green','blue']animals=['cat','dog','horse','sheep']results=[]forxincolors: #顏色

foryinanimals: #動物

results+=[x+''+y]請記錄:閱讀代碼,分析results的運行結果_____________________。4.1.1解析for循環(huán)4.1.1解析for循環(huán)最后,results將會是['redcat','reddog','redhorse','redsheep','greencat','greendog','greenhorse','greensheep','bluecat','bluedog','bluehorse','bluesheep']。4.1.2程序?qū)嵗河嬎阋幌盗袛?shù)字的平均值計算用戶輸入的一系列數(shù)字的平均值,這個程序應該適用于任意大小的數(shù)字。通常,平均值是通過對數(shù)字求和并除以數(shù)字的個數(shù)來計算的。程序不需要記錄輸入的數(shù)字,只需要一個不斷增長的總和,以便最后計算出平均值。4.1.2程序?qū)嵗河嬎阋幌盗袛?shù)字的平均值考慮到這里需要處理一系列數(shù)字,它們將由某種形式的循環(huán)來處理。如果有n個數(shù)字,循環(huán)應該執(zhí)行n次,可以用計數(shù)的循環(huán)模式。我們還需要一個不斷增長的總和,這需要一個循環(huán)累積器。將兩個想法結合在一起,可以描述設計如下:輸入數(shù)字的個數(shù),n初始化為0循環(huán)n次輸入一個數(shù)字,x

將x添加到總計輸出平均值為總數(shù)/n【程序?qū)嵗?-3】計數(shù)循環(huán)和累積器。#average1.pydefmain():n=int(input("有多少個數(shù)字?"))total=0.0foriinrange(n):x=float(input("輸入一個數(shù)字>>"))total=total+xprint("\n這些數(shù)字的平均值是",total/n)main()請記錄:上面代碼的運行結果__________________________________4.1.2程序?qū)嵗河嬎阋幌盗袛?shù)字的平均值4.1.2程序?qū)嵗河嬎阋幌盗袛?shù)字的平均值不斷增長的總和從0開始,依次加上每個數(shù)字。循環(huán)后,將總和除以n,計算平均值。通過這個小程序,我們了解了一些常見的模式,計數(shù)循環(huán)和累積器。4.1.3程序?qū)嵗和顿Y的終值下面,我們通過開發(fā)一個確定投資終值的程序來熟悉編程過程。我們知道存入銀行賬戶的錢會賺取利息,這個利息隨著時間的推移而累積。從現(xiàn)在起10年后,一個賬戶將有多少錢呢?顯然,這取決于開始時有多少錢(本金)以及賬戶賺多少利息。給定本金和利率,程序就能夠計算出未來10年投資的終值。4.1.3程序?qū)嵗和顿Y的終值制定程序的規(guī)格說明。需要用戶輸入初始投資金額,即本金。還需要說明賬戶賺多少利息。處理此問題的一種簡單方法是讓用戶輸入年度百分比率,年利率告訴我們一年內(nèi)的投資收益。如果年利率為3%,那么100美元的投資在一年時間內(nèi)增長到103美元,因此利率將輸入為0.03。得到以下規(guī)格說明:程序終值輸入

principal投資于美元的金額

APR以十進制數(shù)表示的年度百分比利率輸出投資10年后的終值。關系一年后的價值由principa1(1+apr)給出。該公式需要應用10次。4.1.3程序?qū)嵗和顿Y的終值接下來使用偽代碼為程序設計一個算法。針對規(guī)格說明,這個算法看起來很簡單:打印介紹輸入本金的金額(principal)輸入年度百分比利率(apr)重復10次:

principa1=principa1*(1+apr)輸出principa1的值4.1.3程序?qū)嵗和顿Y的終值事實上,在這個設計中并不一定要用循環(huán)。有一個公式可以利用乘冪一步就能算出終值。不過在這里,我們想借這個例子來說明循環(huán)方法。知道如何計算一年的利息,就能計算未來任意年數(shù)的利息?,F(xiàn)在編寫一個Python程序,上面算法的每一步都轉(zhuǎn)換為一條Python語句。要注意的是,計數(shù)循環(huán)模式應用了10次利息公式?!境绦?qū)嵗?-4】計算未來10年投資價值。#futval.py#計算未來10年投資價值的程序defmain():print("這個程序計算10年投資的未來價值。") #打印介紹

principal=eval(input("輸入初始本金:")) #輸入本金

apr=eval(input("輸入年利率:")) #輸入年度百分比利率

foriinrange(10): #重復10次(計數(shù)循環(huán))

principal=principal*(1+apr) #計算(賦值)

print("10年的價值是:",principal) #輸出計算結果main()請記錄:上面代碼的運行結果為_________________________________________________4.1.3程序?qū)嵗和顿Y的終值均值4.1.3程序?qū)嵗和顿Y的終值在程序中添加了幾個空行來分隔程序的輸入、處理和輸出部分。在程序設計中策略性地放置“空行”能增加程序的可讀性。4.2

while循環(huán)語句解析while循環(huán) 程序?qū)嵗河嬎憧偡峙c平均分4.2while循環(huán)語句程序?qū)嵗?-1的求平均值程序首先需要用戶明確有多少個數(shù)字,這在數(shù)字不多時是可以的。但是,如果有很多數(shù)字需要參與求平均值呢?可見我們需要使用另一種循環(huán),即“不定循環(huán)”或“條件循環(huán)”,一個獨立循環(huán)保持迭代,直到滿足某些條件,而事先則無須確定循環(huán)次數(shù)。在Python中用while語句實現(xiàn)不定循環(huán),語法上非常簡單:while<條件>:<循環(huán)體>從“while”到“:”,稱為“頭(head)”,而里面的所有程序語句,則稱為“循環(huán)體”。<條件>是一個布爾表達式,通常<循環(huán)體>是一個或多個語句的序列。while的語義很簡單。只要條件保持為真,循環(huán)體就會重復執(zhí)行。當條件為False時,循環(huán)終止。4.2.1解析while循環(huán) 見圖,在循環(huán)體執(zhí)行前,始終在循環(huán)頂部進行條件測試。這種結構稱為“先測試”循環(huán)。如果循環(huán)條件最初就為假,則循環(huán)體根本就不會執(zhí)行。

while循環(huán)的流程圖4.2.1解析while循環(huán) 例如下面的程序可從1加到100,最后x應等于5050。i=1x=0whilei<=100: #循環(huán)頭

x+=i #循環(huán)體

i+=1 #循環(huán)體在這組程序代碼中,我們利用i來控制while循環(huán),首輪時i是0,“i<=100”比較表達式為真,所以進入循環(huán)體,循環(huán)體最后一行讓i加1,然后程序流程會再回到循環(huán)頭的表達式,重復以上步驟,直到表達式的結果為假,也就是當i大于100時,會跳出循環(huán),從整個循環(huán)的下一行程序代碼繼續(xù)執(zhí)行。4.2.1解析while循環(huán) 我們稱呼這種程序形式為重復執(zhí)行或迭代,迭代與循環(huán)可以看成是同義詞,重復執(zhí)行同樣的程序代碼,直到某件事為假。while語句的簡單性讓它既強大又危險。因為不那么嚴格,所以更為通用,它可以做的不只是遍歷序列。但它也是錯誤的常見來源。例如,假設我們忘記在循環(huán)體的底部增加i:i=0whilei<=10:print(i)該程序的輸出是什么?這是一個“無限循環(huán)”(又稱“死循環(huán)”)。如果發(fā)生了死循環(huán),通常通過按<Ctrl>-C退出循環(huán)。如果循環(huán)非常忙而無法打斷,恐怕就要使用“暴力”手段了(例如同時按<Ctrl>-<Alt>-<Delete>鍵)。當然,最好是開始就避免寫出無限循環(huán)。4.2.2程序?qū)嵗河嬎憧偡峙c平均分下面是一個簡單的while循環(huán),從0數(shù)到10:i=0whilei<=10:print(i)i=i+1這個while循環(huán)的效果與下面的for循環(huán)是一樣的:foriinrange(11):print(i)注意到,while要求在循環(huán)之前對循環(huán)變量(i)初始化,并在循環(huán)體底部讓i增加(i=i+1),而在for循環(huán)中,循環(huán)變量是自動處理的?!境绦?qū)嵗?-5】計算總分與平均分。#while_score.pyscores=[60,73,81,95,34]n=5 #目前寫5,以后將由程序求出列表長度i=0total=0 #total最后將是總分whilei<5:total+=scores[i]i+=1avg=total/n #avg是平均分請記錄:閱讀代碼,運行結果________________________________________4.2.2程序?qū)嵗河嬎憧偡峙c平均分4.2.2程序?qū)嵗河嬎憧偡峙c平均分這個程序中,假定列表中的數(shù)字代表某學生的成績,運用循環(huán)求得總分,然后算出平均成績。試想一下,如果忘記在循環(huán)體的底部增加i,會發(fā)生什么?4.3

break語句與continue語句4.3break語句與continue語句使用循環(huán)語句時,有時在處理到循環(huán)的某一輪時,就已經(jīng)達到目標不必再繼續(xù)執(zhí)行,此時可使用break語句立即跳出循環(huán)。例如,假如只想得知有無不及格(低于60分)的成績即可,程序如下:【程序?qū)嵗?-6】for與break。#for_break.pyscores=(98,78,64,55,61,82)lower_than_60=Falseforxinscores:ifx<60: #只要有一科低于60分

lower_than_60=Truebreak #跳出循環(huán)請記錄:閱讀代碼,運行結果__________________________________4.3break語句與continue語句4.3break語句與continue語句break語句只能跳出一個循環(huán),也就是與break語句最靠近的那一層循環(huán)。假設給你一組數(shù)字,希望求出總和,但里頭有些錯誤的數(shù)據(jù),這是就可以使用break語句跳過那些不需要處理的數(shù)據(jù),程序如下?!境绦?qū)嵗?-7】兩重循環(huán)與break。#for_break_nested.pydata=[[33,44,55],[18381,99781],[60,70,42,91],[32,51]]total=0forxindata:foryinx:if0<=y<=100: #判斷數(shù)據(jù)是否正確

total+=yelse: #錯誤的數(shù)據(jù),全部舍棄

break請記錄:閱讀代碼,運行結果__________________________________4.3break語句與continue語句4.3break語句與continue語句有時,當循環(huán)執(zhí)行到某個位置時,就知道不必再繼續(xù)執(zhí)行這一輪了,想要立即跳回循環(huán)頭繼續(xù)執(zhí)行下一輪,此時可使用continue語句。例如只想計算超過60分成績的平均成績,也就是說不必處理低于60分的成績?!境绦?qū)嵗?-8】計算超過60分成績的平均成績。#for_high.pyscores=[60,73,81,95,34]n=0high_total=0forxinscores:ifx<60: #低于60分

continue #直接跳到下一輪

n+=1high_total+=x請記錄:閱讀代碼,運行結果__________________________________4.3break語句與continue語句4.3break語句與continue語句不過,上面這個程序代碼可以改成不使用continue語句。舉個稍微復雜一點的例子。有一班學生的成績太差,老師決定給每人加10分,但上限是90分,而且原本已經(jīng)大于90分的成績保持不變,程序如下?!境绦?qū)嵗?-9】加分。#score_plus.pyscores=[30,99,41,55,84]scores_new=[] #存放加分后的成績forxinscores:ifx>=90: #原始成績已經(jīng)大于90scores_new+=[x] #直接放進去就好了

continue #下面的程序代碼無須執(zhí)行,繼續(xù)下一輪即可

x+=10 #加10分

ifx>=90: #超過加分上限

x=90scores_new+=[x] #放進去請記錄:閱讀代碼,運行結果______________________________________________4.3break語句與continue語句4.4

常見循環(huán)模式交互式循環(huán)哨兵循環(huán)、文件循環(huán)嵌套循環(huán)、后測試循環(huán)循環(huán)加一半循環(huán)語句中的else子句4.4

常見循環(huán)模式在程序設計中,循環(huán)語句的應用非常廣泛,下面學習一些典型的循環(huán)運用。4.4.1交互式循環(huán)不定循環(huán)有一個很好的用途,就是用來編寫交互式循環(huán),具體想法是,允許用戶根據(jù)需要重復程序的某些部分。下面以對數(shù)字求平均值為例。我們修改求平均值程序,使其記錄有多少個數(shù)字參與計算。我們加一個累積器(稱為count)來計數(shù),它從0開始,每循環(huán)一次就加1。為了允許用戶在任何時間停止,循環(huán)中每次迭代時將詢問是否有更多的數(shù)據(jù)要處理。交互式循環(huán)的一般模式如下:將moredata設為“yes”當moredata為“yes”時獲取下一個數(shù)據(jù)項處理該項目詢問用戶是否有更多數(shù)據(jù)要處理4.4.1交互式循環(huán)將交互式循環(huán)模式與累積器相結合,得到這個求平均值的程序算法:初始化total為0.0將count初始化為0將moredata設為“yes”當moredata為“yes”時輸入一個數(shù)字,x

將x添加到totalcount加1

詢問用戶是否有更多數(shù)據(jù)要處理輸出total/count【程序?qū)嵗?-10】兩個累積器是如何交織在交互式循環(huán)的基本結構中。#average2.pydefmain():total=0.0count=0moredata="yes"whilemoredata[0]=="y":x=float(input("輸入一個數(shù)字>>"))total=total+xcount=count+1moredata=input(“還有更多的數(shù)據(jù)嗎(yesorno)?")print("\n這組數(shù)據(jù)的平均值是",total/count)main()請記錄:上面代碼的運行結果為________________________________4.4.1交互式循環(huán)4.4.1交互式循環(huán)該程序使用字符串索引(moredata[0])來查看用戶輸入的第一個字母。這樣可以做出各種各樣的響應,例如“yes”、“y”、“yeah”等。重要的是第一個字母是“y”。在這個版本中,用戶不必對數(shù)據(jù)值進行計數(shù),但是用戶幾乎肯定會因為不斷提示是否有更多數(shù)據(jù)而感到煩惱。4.4.2哨兵循環(huán)哨兵循環(huán)是一種常見的編程模式,它可能是解決求數(shù)字平均值問題的更好方案。哨兵循環(huán)不斷循環(huán)處理輸入的數(shù)據(jù),直到遇到表明迭代結束的特殊值,這個特殊值就稱為“哨兵”??梢赃x擇任何值作為哨兵,唯一限制是其能與實際數(shù)據(jù)值區(qū)分開來。哨兵不作為數(shù)據(jù)的一部分進行處理。下面是設計哨兵循環(huán)的一般模式:獲取第一個數(shù)據(jù)項當這個數(shù)據(jù)項不是哨兵處理該項目獲取下一個數(shù)據(jù)項4.4.2哨兵循環(huán)請注意這種模式如何避免處理哨兵。在循環(huán)開始之前取得第一項數(shù)據(jù),如果第一項就是哨兵,循環(huán)將立即終止,不會處理任何數(shù)據(jù)。否則,處理該項數(shù)據(jù),并讀取下一項。循環(huán)頂部的測試確保下一項不是哨兵并處理它。如果遇到哨兵,則循環(huán)終止。我們將哨兵模式應用于數(shù)字平均值問題。第一步是選擇哨兵。假設我們正在使用該程序來計算考試成績的平均值。在這種情況下,我們可以放心地假設沒有得分低于0,用戶可以輸入負數(shù)來表示數(shù)據(jù)結束(即某個負數(shù)成為“哨兵”)。【程序示例4-11】這個程序結合了哨兵循環(huán)和來自交互式循環(huán)版本的兩個累積器。#average3.pydefmain():total=0.0count=0x=float(input("輸入一個數(shù)字(負數(shù)退出)>>"))whilex>=0:total=total+xcount=count+1x=float(input("輸入一個數(shù)字(負數(shù)退出)>>"))print("\n這組數(shù)據(jù)的平均值是",total/count)main()請記錄:上面代碼的運行結果為_________________________________________________4.4.2哨兵循環(huán)4.4.2哨兵循環(huán)注意到,提醒用戶知道如何表明數(shù)據(jù)結束的提示安排在啟動讀入或者循環(huán)體底部效果是相同的。這個程序既提供了交互式循環(huán)的易用性,又省去了一直輸入“yes”的麻煩。哨兵循環(huán)是非常方便的解決各種數(shù)據(jù)處理問題的模式。這個程序還有個瑕疵,如果輸入的第一個數(shù)字就是負數(shù),會出現(xiàn)什么問題?怎么調(diào)整?不過這個解決方案還存在一個限制,該程序不能用于對一組既包含負值又包含正值的數(shù)字求平均值。為使這個程序更通用,我們需要一個特殊的哨兵值。4.4.2哨兵循環(huán)為了擁有一個真正獨特的哨兵,需要擴大可能的輸入。假設我們將用戶的輸入作為字符串獲取,就可以設定一個非數(shù)字字符串作為哨兵,用來表示輸入結束,而所有其他輸入都將被轉(zhuǎn)換為數(shù)字并視為數(shù)值。一個簡單的解決方案是將一個空字符串作為哨兵值,空字符串在Python中被表示為""(引號之間沒有空格)。如果用戶響應輸入時鍵入空白行(只需輸入回車鍵),Python將返回一個空字符串。4.4.2哨兵循環(huán)可以用這個方法來終止輸入,偽代碼設計如下:initializetotalto0.0initializecountto0inputdataitemasastring,xStrwhilexStrisnotemptyconvertxStrtoanumber,xaddxtototaladd1tocountinputnextdataitemasastring,xStroutputtotal/count【程序?qū)嵗?-12】將字符串轉(zhuǎn)換為數(shù)字添加到哨兵循環(huán)的處理部分。#average4.pydefmain():total=0.0count=0xStr=input("輸入一個數(shù)字(按回車鍵退出)>>")whilexStr!="":x=float(xStr)total=total+xcount=count+1xStr=input("輸入一個數(shù)字(按回車鍵退出)>>")print("\n這組數(shù)據(jù)的平均值是",total/count)main()請記錄:上面代碼的運行結果為_________________________________________________這段代碼檢查并確保輸入不是哨兵("")后,通過float將輸入轉(zhuǎn)換成數(shù)字。4.4.2哨兵循環(huán)4.4.3文件循環(huán)到目前為止,所有平均值程序都是互動方式的。想象一下,如果正在嘗試求87個數(shù)字的平均值,而恰巧在接近尾聲時發(fā)生了打字錯誤,那么,使用這個程序恐怕就需要重頭開始了。處理該問題的更好方法,是將所有數(shù)字先輸入到文件中,文件中的數(shù)據(jù)可以仔細考察并編輯,再發(fā)送給程序,生成報告。這種面向文件的方法常常用于數(shù)據(jù)處理應用程序。Python將文件視為一系列行,因此,使用for循環(huán)逐行處理文件尤其容易。我們可以將這種技術直接應用于求數(shù)字平均值問題。例如,準備一個文件test.txt,里面逐行存放數(shù)字32、88、99、22、33、55。執(zhí)行下列程序?!境绦?qū)嵗?-13】假設數(shù)字被輸入一個文件,每行一個,用程序計算平均值。#average5.pydefmain():fileName=input("這些數(shù)字在哪個文件里?")infile=open(fileName,'r')total=0.0count=0forlineininfile:total=total+float(line)count=count+1print("\n這組數(shù)據(jù)的平均值是",total/count)main()請記錄:上面代碼的運行結果為_________________________________________________4.4.3文件循環(huán)4.4.3文件循環(huán)在這段代碼中,循環(huán)變量line將文件作為行序列,遍歷該文件。每行被轉(zhuǎn)換為一個數(shù)字,并加到不斷增長的總和中。readline()方法從文件中獲取下一行作為字符串,在文件末尾,readline()返回一個空字符串,我們可以用它作為哨兵值。下面是Python中使用readline()的“文件結束循環(huán)”的一般模式。line=infile.readline()whileline!="":#處理lineline=infile.readline()我們不用擔心文件中遇到空行會導致該循環(huán)過早停止。因為文本文件中的空白行包含單個換行符(\n),"\n"不等于"",所以循環(huán)將繼續(xù)。【程序?qū)嵗?-14】將文件結束哨兵循環(huán)應用于數(shù)字平均值問題。還是準備一個文件test.txt,里面逐行存放數(shù)字32、88、99、22、33、55。執(zhí)行下列程序。#average6.pydefmain():fileName=input("這些數(shù)字在哪個文件里?")infile=open(fileName,'r')total=0.0count=0line=infile.readline()whileline!="":total=total+float(line)count=count+1line=infile.readline()print("\n這組數(shù)據(jù)的平均值是",total/count)main()請記錄:上面代碼的運行結果為_________________________________________________顯然,這個版本不如使用for循環(huán)那樣簡潔,不過我們就此了解了用文件結束循環(huán)的形式。4.4.3文件循環(huán)4.4.4嵌套循環(huán)我們討論過判斷和循環(huán)這樣的控制結構如何嵌套在一起產(chǎn)生復雜的算法。像其他控制結構一樣,循環(huán)也可以嵌套。我們來看一個例子。修改一下基于文件求平均值問題的規(guī)格說明,這一次不是每行輸入一個數(shù)字,而是允許一行包含任何數(shù)目的值。如果一行上出現(xiàn)多個值,則以逗號分隔。4.4.4嵌套循環(huán)在頂層,基本算法是文件處理循環(huán),計算不斷增長的總和與計數(shù),其中使用文件結束循環(huán)。total=0.0count=0line=infile.readline()whileline!="":#更新行的總數(shù)和計數(shù)

line=infile.readline()print("\n這組數(shù)據(jù)的平均值是",total/count)4.4.4嵌套循環(huán)那么,如何更新循環(huán)體中的總數(shù)和計數(shù)呢?由于文件中每個單獨的行包含一個或多個由逗號分隔的數(shù)字,所以我們可以將該行分割成子字符串,每個代表一個數(shù)字。然后,需要循環(huán)遍歷這些子字符串,將每個子字符串轉(zhuǎn)換成一個數(shù)字,并將它加到total中。對每個數(shù)字,還需要讓count加1。這是處理一行的代碼片段:forxStrinline.split(","):total=total+float(xStr)count=count+1請注意,此片段中的for循環(huán)的迭代由line的值控制,它正是上面我們簡要描述的文件處理循環(huán)的循環(huán)控制變量?!境绦?qū)嵗?-15】將兩個循環(huán)編織在一起的程序。#average7.pydefmain():fileName=input("這些數(shù)字在哪個文件里?")infile=open(fileName,'r')total=0.0count=0line=infile.readline()4.4.4嵌套循環(huán)whileline!="":#更新行的總數(shù)和計數(shù)

forxStrinline.split(","):total=total+float(xStr)count=count+1line=infile.readline()print("\n這組數(shù)據(jù)的平均值是",total/count)main()請記錄:上面代碼的運行結果為_______________________________________4.4.4嵌套循環(huán)4.4.4嵌套循環(huán)處理一行中數(shù)字的循環(huán)在文件處理循環(huán)內(nèi)縮進。外層while循環(huán)對文件的每一行進行一次迭代。在外層循環(huán)的每次迭代中,內(nèi)層for循環(huán)迭代的次數(shù)等于該行中數(shù)字的次數(shù)。內(nèi)層循環(huán)完成時,文件的下一行被讀入,外層循環(huán)進行下一次迭代。這個問題的單個片段并不復雜,但最終的結果有點復雜。設計嵌套循環(huán)算法時,最好一次考慮一個循環(huán),先設計外層,不考慮內(nèi)層的內(nèi)容,然后設計內(nèi)層的內(nèi)容,忽略外層循環(huán)。最后放在一起,注意保留嵌套。如果單個循環(huán)是正確的,則嵌套的結果就會正常工作。4.4.5后測試循環(huán)判斷結構(if)以及先測試循環(huán)(while)提供了一套完整的控制結構,每個算法都可以用這些結構來表示。原則上,掌握了while和if,就能寫出所有希望得到的算法。然而,對于某些類型問題,替代結構有時可能會比較方便。假設你正在編寫一個輸入算法,該算法需要從用戶那里獲取一個非負數(shù)。如果用戶鍵入錯誤,則程序會要求重新輸入。它不斷重新提示,直到用戶輸入一個有效值。這個過程稱為輸入驗證,精心設計的程序應該盡可能地驗證輸入。4.4.5后測試循環(huán)下面是一個簡單的算法:Repeat

從用戶那里得到一個號碼untilnumberis>=0思路是循環(huán)持續(xù)取得輸入,直到該值可以接受(有效)。描述該設計的流程圖如圖所示。這是一個“后測試循環(huán)”,算法中必須至少執(zhí)行一次循環(huán)體,其條件測試在循環(huán)體之后進行。

測試后循環(huán)的流程圖4.4.5后測試循環(huán)Python沒有直接實現(xiàn)后測試循環(huán)的語句,該算法可以用while來實現(xiàn),只要預設第一次迭代的循環(huán)條件:number=-1 #以非法值開始進入循環(huán)whilenumber<0:number=float(input("輸入一個正數(shù):"))程序迫使循環(huán)體至少執(zhí)行一次。注意到這與先前給出的交互式循環(huán)模式結構類似。4.4.5后測試循環(huán)一些程序員喜歡用break語句來直接模擬后測試循環(huán),執(zhí)行break會導致Python立即退出圍繞它的循環(huán)。通常這樣的設計在語法上像是無限循環(huán)。下面是用break實現(xiàn)的相同算法:whileTrue:number=float(input("輸入一個正數(shù):"))ifnumber>=0:break #如果數(shù)字有效,則退出循環(huán)只要循環(huán)頭中的表達式求值為真,while循環(huán)就會繼續(xù)。True始終為真,但是當x的值為非負數(shù)時,執(zhí)行break語句,循環(huán)終止。請注意,這里將break放在if同一行上,如果if的body只包含一個語句,這是合法的。常??吹絾涡械膇f-break組合用作循環(huán)出口。4.4.5后測試循環(huán)我們再對這個小程序做點改進,讓程序發(fā)出提示,說明輸入無效。在后測試循環(huán)的while版本中,需要添加一個if,這樣輸入有效時不顯示警告。number=-1 #以非法值開始進入循環(huán)whilenumber<0:number=float(input("輸入一個正數(shù):"))ifnumber<0:print("您輸入的數(shù)字不是正數(shù)")4.4.5后測試循環(huán)為break添加警告,只要在原有的if添加一個else。whileTrue:number=float(input(“輸入一個正數(shù):”))ifnumber>=0:break #如果數(shù)字有效,則退出循環(huán)

e1se:print("您輸入的數(shù)字不是正數(shù)")4.4.6循環(huán)加一半構建非標準的循環(huán)結構,可以用循環(huán)條件為True的while循環(huán),并用break語句來提供循環(huán)出口。我們來看一個不同風格的提示設計:whileTrue:number=float(input("輸入一個正數(shù):"))ifnumber>=0:break #退出循環(huán)

print("您輸入的數(shù)字不是正數(shù)")這里的循環(huán)出口安排在循環(huán)體的中間,我們把它稱為“循環(huán)加一半”。循環(huán)加一半是避免在哨兵循環(huán)中啟動讀取的較好方式。4.4.6循環(huán)加一半下面是用循環(huán)加一半來實現(xiàn)哨兵循環(huán)的一般模式:

哨兵循環(huán)模式的循環(huán)加一半實現(xiàn)4.4.6循環(huán)加一半當為真時:

得到下一個數(shù)據(jù)項如果該項目是哨兵:退出(break)處理該項目可以看到,這個實現(xiàn)忠實于哨兵循環(huán)的第一規(guī)則――避免處理哨兵值。要注意避免在一個循環(huán)體中塞進多個break語句。如果有多個出口,循環(huán)的邏輯容易失控。4.4.7循環(huán)語句中的else子句for與while語句還能再加上else子句,例如下面的程序會檢查列表numbers里是否有偶數(shù)。numbers=[1,5,13,7,2,9]hasEven

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論