Python程序設(shè)計(jì)基礎(chǔ)第三章 流程控制語句_第1頁
Python程序設(shè)計(jì)基礎(chǔ)第三章 流程控制語句_第2頁
Python程序設(shè)計(jì)基礎(chǔ)第三章 流程控制語句_第3頁
Python程序設(shè)計(jì)基礎(chǔ)第三章 流程控制語句_第4頁
Python程序設(shè)計(jì)基礎(chǔ)第三章 流程控制語句_第5頁
已閱讀5頁,還剩85頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

匯報人:WPSPython程序設(shè)計(jì)基礎(chǔ)第三章基礎(chǔ)語法概述目錄01選擇結(jié)構(gòu):if語句02循環(huán)結(jié)構(gòu):while和for語句03循環(huán)結(jié)構(gòu):break和continue語句04pass語句目錄05Python生態(tài)系統(tǒng)之random庫06小試牛刀07拓展實(shí)踐:隨機(jī)數(shù)是如何生成的

牢固掌握if語句。深入理解循環(huán)結(jié)構(gòu)的執(zhí)行過程。熟練使用while、for語句構(gòu)造循環(huán)結(jié)構(gòu)。理解break、continue語句的作用與區(qū)別。理解pass語句的作用。掌握random庫中常用函數(shù)的使用方法。學(xué)習(xí)目標(biāo)PART13.1選擇結(jié)構(gòu):if語句3.1.1if語句的基本形式在第

2

章結(jié)尾的模擬自動售貨機(jī)找零案例及更早的輸出《少年中國說》一段文字案例中(參見

代碼

2.5

2.28)已經(jīng)用到了

if

語句。if

語句體現(xiàn)的是程序流程中的選擇結(jié)構(gòu),程序運(yùn)行到

if

語句

時,要根據(jù)

if

語句中條件表達(dá)式的真假來選擇一條分支執(zhí)行,不同的分支對應(yīng)著不同的代碼塊。下

面看一個具體的例子,代碼3.1

從鍵盤接收一句詩詞,然后判斷詩句中是否含有指定的關(guān)鍵字,根

據(jù)判斷結(jié)果的真假給出不同的反饋。if

語句包含的表達(dá)式keyword

in

poem其運(yùn)算結(jié)果只能是

True

False。如果表達(dá)式的結(jié)果為

True,則程序執(zhí)行

if

后面縮進(jìn)的代碼塊;如果表達(dá)式的結(jié)果為False,

則程序執(zhí)行

else后面縮進(jìn)的代碼塊。這兩個被縮進(jìn)的代碼塊就是

if

語句的兩個分支,一個由

if

引導(dǎo),

一個由

else引導(dǎo),因此在

if

else所在行的行尾都有一個冒號。注意,else只是引導(dǎo)

if

語句的一個

分支,它是

if

語句的一部分,并不是一個獨(dú)立的語句。3.1.1if語句的基本形式代碼

3.1

if

語句基本形式示例poem=input("請輸入一句含“風(fēng)”字的詩詞:")keyword=

"風(fēng)"ifkeyword

inpoem:print("您輸入的詩句包含",keyword,"字。")print("恭喜,回答正確。")else:print("很遺憾,回答錯誤。")print("您輸入的詩句不包含",keyword,"字。")3.1.1if語句的基本形式代碼

3.2

多分支的

if

語句print("中國有四大石窟,想了解它們的信息嗎?")id=input("請輸入序號(1~4):")if

id==

"1":msg="莫高窟,位于敦煌市東南

25

千米處。"

\"公元

366

年沙門樂尊行至此處,見鳴沙山上金光萬道,"\"狀有千佛,于是萌發(fā)開鑿之心。"\"從此歷經(jīng)千載不斷開鑿,遂成佛門圣地。"\"莫高窟是集建筑、彩塑、壁畫為一體的文化藝術(shù)寶庫,"\"具有珍貴的歷史、藝術(shù)、科學(xué)價值,"\"是中華民族的歷史瑰寶,人類優(yōu)秀的文化遺產(chǎn)。"elif

id==

"2":msg="麥積山石窟,地處甘肅省天水市東南方

30

千米的"\"麥積山鄉(xiāng)南側(cè)西秦嶺山脈的一座孤峰上,"\"因形似麥垛而得名。麥積山石窟的一個顯著特點(diǎn)是"\"洞窟所處位置極其驚險,大都開鑿在懸崖峭壁之上,"\"洞窟之間全靠架設(shè)在崖面上的凌空棧道通達(dá)。"\"在中國的著名石窟中,自然景色以麥積山石窟為最佳。"3.1.1if語句的基本形式選擇結(jié)構(gòu)的分支數(shù)量可多可少,要根據(jù)實(shí)際需要來定。例如,在第2章的代碼2.28中if語句就只有一個分支,并沒有出現(xiàn)else分支。而有的時候,if語句則需要多于兩個的分支,此時,if語句就會出現(xiàn)由elif引領(lǐng)的分支,如下面代碼3.2所示的例子。代碼

3.2

多分支的

if

語句elif

id==

"3":msg="云岡石窟位于中國北部山西省大同市以西

16

千米處的武周山南麓。"\"石窟依山而鑿,東西綿亙約

1千米,氣勢恢弘,內(nèi)容豐富。"\"窟中菩薩、力士、飛天形象生動活潑,塔柱上的雕刻精致細(xì)膩,"\"上承秦漢現(xiàn)實(shí)主義藝術(shù)的精華,下開隋唐浪漫主義色彩之先河。"elif

id==

"4":msg="龍門石窟位于洛陽市東南,分布于伊水兩岸的崖壁上,"\"南北長達(dá)

1千米。石窟始鑿于北魏年間,先后營造

400

多年。"\"現(xiàn)存窟龕

2300

多個,雕像

10萬余尊,"\"是中國古代雕刻藝術(shù)的典范之作。"else:msg=

"請輸入

1~4

之間的整數(shù)。"print(msg)3.1.1if語句的基本形式代碼

3.2

多分支的

if

語句elif

id==

"3":msg="云岡石窟位于中國北部山西省大同市以西

16

千米處的武周山南麓。"\"石窟依山而鑿,東西綿亙約

1千米,氣勢恢弘,內(nèi)容豐富。"\"窟中菩薩、力士、飛天形象生動活潑,塔柱上的雕刻精致細(xì)膩,"\"上承秦漢現(xiàn)實(shí)主義藝術(shù)的精華,下開隋唐浪漫主義色彩之先河。"elif

id==

"4":msg="龍門石窟位于洛陽市東南,分布于伊水兩岸的崖壁上,"\"南北長達(dá)

1千米。石窟始鑿于北魏年間,先后營造

400

多年。"\"現(xiàn)存窟龕

2300

多個,雕像

10萬余尊,"\"是中國古代雕刻藝術(shù)的典范之作。"else:msg=

"請輸入

1~4

之間的整數(shù)。"print(msg)3.1.1if語句的基本形式首先,要明確的是代碼3.2中的if語句仍然是一個語句,只是有5個分支。在這5個分支中,由if或elif引導(dǎo)的分支都有一個條件表達(dá)式,該表達(dá)式為True時才執(zhí)行相應(yīng)分支的代碼塊。如果前面所有的分支條件均為False,則執(zhí)行else分支。因此程序遇到if語句時,會依次判斷每個分支的條件,找到第一個條件成立的分支,執(zhí)行該分支下的代碼塊,則其他分支下的代碼就沒有機(jī)會被執(zhí)行了,程序會跳到if語句后面的位置繼續(xù)執(zhí)行if語句之后的代碼。其次,輸入的序號并沒有被轉(zhuǎn)為整型,因此變量

id

中保存的是字符串。if

語句的比較表達(dá)式中序號均是字符串類型。如果在

input()函數(shù)外套上

int()函數(shù),將輸入的序號轉(zhuǎn)換為整型,則

if

語句的

比較表達(dá)式中的序號要為整數(shù),讀者可自行嘗試修改代碼。再次,由于

if

語句在執(zhí)行時,一旦找到第一個條件成立的分支,其后的其他分支就不予考慮了,

因此在書寫多分支的

if

語句時,要注意這一點(diǎn)。例如,下面代碼

3.3

if

語句的多個分支書寫順序

就有問題,導(dǎo)致中間由

elif引導(dǎo)的

3

個分支永遠(yuǎn)沒有機(jī)會被執(zhí)行。閱讀這段代碼時要注意其中的粗

體部分,那是與代碼

3.2

的不同之處。3.1.1if語句的基本形式代碼

3.3

if

語句多分支的書寫順序#書寫順序不對,導(dǎo)致中間的

3個

elif分支失效print("中國有四大石窟,想了解它們的信息嗎?")id=int(input("請輸入序號(1~4):"))ifid>=

1:msg="莫高窟,位于敦煌市東南

25

千米處。"

\"公元

366

年沙門樂尊行至此處,見鳴沙山上金光萬道,"\"狀有千佛,于是萌發(fā)開鑿之心。"\"從此歷經(jīng)千載不斷開鑿,遂成佛門圣地。"\"莫高窟是集建筑、彩塑、壁畫為一體的文化藝術(shù)寶庫,"\"具有珍貴的歷史、藝術(shù)、科學(xué)價值,"\"是中華民族的歷史瑰寶,人類優(yōu)秀的文化遺產(chǎn)。"elifid>=2:msg="麥積山石窟,地處甘肅省天水市東南方

30

千米的"\"麥積山鄉(xiāng)南側(cè)西秦嶺山脈的一座孤峰上,"\"因形似麥垛而得名。麥積山石窟的一個顯著特點(diǎn)是"\"洞窟所處位置極其驚險,大都開鑿在懸崖峭壁之上,"\"洞窟之間全靠架設(shè)在崖面上的凌空棧道通達(dá)。"\"在中國的著名石窟中,自然景色以麥積山石窟為最佳。"3.1.1if語句的基本形式代碼

3.3

if

語句多分支的書寫順序elifid>=3:msg="云岡石窟位于中國北部山西省大同市以西

16

千米處的武周山南麓。"\"石窟依山而鑿,東西綿亙約

1千米,氣勢恢弘,內(nèi)容豐富。"\"窟中菩薩、力士、飛天形象生動活潑,塔柱上的雕刻精致細(xì)膩,"\"上承秦漢現(xiàn)實(shí)主義藝術(shù)的精華,下開隋唐浪漫主義色彩之先河。"elifid>=4:msg="龍門石窟位于洛陽市東南,分布于伊水兩岸的崖壁上,"\"南北長達(dá)

1千米。石窟始鑿于北魏年間,先后營造

400

多年。"\"現(xiàn)存窟龕

2300

多個,雕像

10萬余尊,"\"是中國古代雕刻藝術(shù)的典范之作。"else:msg=

"請輸入

1~4

之間的整數(shù)。"print(msg)3.1.1if語句的基本形式對于多分支

if

語句中出現(xiàn)的

elif,其地位與

else類似,都只是

if

語句中的一個分支,只不過

elif

后面有條件表達(dá)式,而

else后面沒有。但無論

else還是

elif

都不是一個獨(dú)立的語句,不能單獨(dú)存在。為了更好地理解

elif,來看下面兩段代碼的對比。代碼

3.4和代碼

3.5

只有一個細(xì)節(jié)不同,即代

3.4

中使用了一個有兩個分支的

if

語句,而代碼

3.5

中使用了兩個獨(dú)立的

if

語句,雖然從文字上

看兩段代碼只相差兩個字母,但兩段代碼的輸出結(jié)果是不同的。在測試時,如果輸入一句只包含“風(fēng)”

字或只包含“花”字的詩句,則兩段代碼的運(yùn)行結(jié)果沒有區(qū)別;但如果輸入類似“夜來風(fēng)雨聲,花

落知多少?!边@樣同時包含兩個字的詩句,則兩段代碼的區(qū)別就顯現(xiàn)出來了。3.1.1if語句的基本形式對于代碼

3.4

而言,因?yàn)槭且粋€

if語句,所以當(dāng)?shù)谝粋€分支成立時,第二個分支是沒有機(jī)會

被執(zhí)行的。因此當(dāng)詩句中含有“風(fēng)”字時,即使還同時含有“花”字,也不會被統(tǒng)計(jì)。而代碼

3.5

因?yàn)槭莾蓚€獨(dú)立的

if

語句,這兩個

if

語句就像兩個關(guān)隘一樣順序串在程序流程上,程序向下執(zhí)行

時一定要將這兩道關(guān)隘都經(jīng)過,兩個

if

語句的條件都要判斷一下。一個

if

語句的代碼是否執(zhí)行只

看自身?xiàng)l件是否成立,與另一個

if

語句無關(guān)。如果各自的條件均為

True,則兩個

if

語句的代碼都

會被執(zhí)行。代碼

3.4

理解

elif

分支(對比代碼

1

)poem=input("請輸入一句含“風(fēng)”“花”二字的詩詞:")keyword_1,keyword_2="風(fēng)","花"grade=

0ifkeyword_1

inpoem:grade+=

1print("詩句包含",keyword_1,"字")elifkeyword_2

inpoem:grade+=

1print("詩句包含",keyword_2,"字")print("最終得分:",grade)3.1.1if語句的基本形式代碼

3.5

理解

elif

分支(對比代碼

2

)poem=input("請輸入一句含“風(fēng)”“花”二字的詩詞:")keyword_1,keyword_2="風(fēng)","花"grade=

0ifkeyword_1

inpoem:grade+=

1print("詩句包含",keyword_1,"字")ifkeyword_2

inpoem:grade+=

1print("詩句包含",keyword_2,"字")print("最終得分:",grade)3.1.2if語句中的條件表達(dá)式在

if

語句中,無論是由if

還是

elif

引導(dǎo)的分支,都要有一個判斷條件,該條件是一個邏輯表達(dá)

式,雖然運(yùn)算結(jié)果只能是

True或

False,但表現(xiàn)形式卻可以五花八門。除了在代碼

3.2和代碼

3.3

展示的由比較運(yùn)算符構(gòu)成的表達(dá)式,以及代碼

3.4和代碼

3.5

中由成員運(yùn)算符構(gòu)成的表達(dá)式,還有很

多其他形式。1.組合條件表達(dá)式組合條件表達(dá)式往往由邏輯運(yùn)算符

and、or

not等參與形成,如代碼

3.6所示。這段代碼模擬了一艘巨型貨輪進(jìn)港停泊的決策過程。巨型貨輪體積巨大,載貨量驚人,航空母艦在它們面前都是

“小個子”。一艘

40萬噸級的貨輪吃水深度可達(dá)到

20米,加之其龐大的體型,普通的港口根本沒有

足夠深的航道和足夠大的碼頭來讓其???。在中國漫長的海岸線上有多個港口可以??窟@種巨型貨

輪,如浙江寧波舟山港。它是世界上吞吐量最大的港口,擁有天然的深水航道和極其現(xiàn)代化的調(diào)度

系統(tǒng),可以??扛鞣N巨型貨輪?,F(xiàn)在假設(shè)某港口擁有

3個巨型貨輪的泊位,最深航道為

20米。當(dāng)一艘巨輪要入港??繒r,基本

的決策條件就如代碼

3.6

所示。只有當(dāng)航道深度大于船的只吃水線深度并且可用泊位大于

0

兩個條

件均為

True時,船只才能入港。3.1.2if語句中的條件表達(dá)式代碼

3.6

if

語句的組合條件表達(dá)式ship_waterline=float(input("入港船只的吃水線深度:"))free_berth_for_huge=3

#可用巨輪泊位depth_of_channel=20

#航道水深iffree_berth_for_huge>0anddepth_of_channel

>

ship_waterline:print("歡迎入港!")free_berth_for_huge-=

1else:print("很遺憾,不能入港。")print("可用巨輪泊位:",free_berth_for_huge)3.1.2if語句中的條件表達(dá)式2.級聯(lián)條件表達(dá)式級聯(lián)條件表達(dá)式形如

3<=x<

10,這種級聯(lián)寫法在中學(xué)數(shù)學(xué)中極為常見,但卻不是程序語言的

常規(guī)寫法。很多程序語言面對這種級聯(lián)條件時,都要拆分為兩個條件的組合,如

3<=x<

10會被寫

x>=3andx<

10這樣的組合條件表達(dá)式。但

Python允許在

if

語句中使用類似中學(xué)數(shù)學(xué)的級聯(lián)條

件,如代碼

3.7所示。3.1.2if語句中的條件表達(dá)式代碼

3.7

if

語句的級聯(lián)條件表達(dá)式population=int(input("你所在城市的人口(單位萬):"))city_level=

""ifpopulation>=

1000:city_level=

"超大城市"elif1000

>population

>=

500:city_level=

"特大城市"elif500

>population

>=

100:city_level=

"大城市"elif100

>population

>=

50:city_level=

"中等城市"else:city_level=

"小城市"print("你所在城市為",city_level)3.1.2if語句中的條件表達(dá)式3.其他數(shù)據(jù)類型轉(zhuǎn)換為邏輯型的條件表達(dá)式在第

2

章介紹數(shù)據(jù)類型時提到了數(shù)據(jù)類型之間的轉(zhuǎn)換,如浮點(diǎn)型轉(zhuǎn)換為整型,字符串轉(zhuǎn)換為數(shù)

值型等。其實(shí)還有一種需要特別說明的類型轉(zhuǎn)換,即其他各種類型向邏輯類型的轉(zhuǎn)換。例如,整數(shù)

或小數(shù)如何轉(zhuǎn)換為

True

False,字符串如何轉(zhuǎn)換為邏輯類型,甚至后續(xù)章節(jié)中介紹的列表、字典

等如何轉(zhuǎn)換為邏輯值。這些數(shù)據(jù)類型向邏輯類型的轉(zhuǎn)換經(jīng)常出現(xiàn)在

if

語句的條件表達(dá)式中。下面的代碼

3.8

演示了整型、字符串等類型向邏輯類型的轉(zhuǎn)換。代碼中每個

if

語句都有兩個分

支,如果

if

后的條件表達(dá)式為真,則執(zhí)行

if

下的print()函數(shù),否則執(zhí)行

else下的print()函數(shù)。3.1.2if語句中的條件表達(dá)式代碼

3.8

其他數(shù)據(jù)類型轉(zhuǎn)換為邏輯類型if

True:print("如果

5>3是

True,那么

True

當(dāng)然也是

True")else:print("if

的條件表達(dá)式恒為

True,因此本分支沒有機(jī)會執(zhí)行")if

0:print("整數(shù)

0相當(dāng)于

True")else:print("整數(shù)

0相當(dāng)于False")if

2:print("非

0整數(shù)相當(dāng)于

True")else:print("非

0整數(shù)相當(dāng)于False")3.1.2if語句中的條件表達(dá)式代碼

3.8

其他數(shù)據(jù)類型轉(zhuǎn)換為邏輯類型if

"":

#空字符串print("空字符串相當(dāng)于

True")else:print("空字符串相當(dāng)于False")if

"

":

#字符串含有一個空格print("非空字符串相當(dāng)于

True")else:

print("非空字符串相當(dāng)于False")3.1.3if語句的嵌套有時

if

語句的某個分支代碼塊中又出現(xiàn)了

if

語句,此時就形成了

if

語句的嵌套。例如,判斷巨

型貨輪能否入港的代碼

3.6其實(shí)也可以寫成下面代碼

3.9

的形式。而且因?yàn)榕袛嗄芊袢敫鄣膬蓚€條件被分開了,所以各自的

else分支可以將不能入港的原因反饋得更到位。PART23.2循環(huán)結(jié)構(gòu):while和for語句3.2循環(huán)結(jié)構(gòu):while和for語句當(dāng)程序中有一項(xiàng)工作需要把類似的操作重復(fù)很多遍時,就意味著循環(huán)結(jié)構(gòu)要登場了。在書寫循

環(huán)結(jié)構(gòu)代碼時,首先要明確循環(huán)的條件是什么,當(dāng)條件滿足時重復(fù)執(zhí)行循環(huán)內(nèi)的代碼,條件不滿足

時循環(huán)結(jié)束。其次要明確循環(huán)體,即每次循環(huán)要做什么工作。最后,要確定有可以改變循環(huán)條件的

語句,否則循環(huán)就成了死循環(huán),永遠(yuǎn)沒有結(jié)束的時候。Python提供了兩個語句來實(shí)現(xiàn)循環(huán)結(jié)構(gòu):while語句和

for語句,它們各有特色,適合不同的

場景。3.2.1while語句1.計(jì)數(shù)控制循環(huán)有一個故事講述了數(shù)學(xué)王子高斯小時候就可以快速地計(jì)算出從

1加到

100

的和,很早就顯示出

非凡的數(shù)學(xué)天賦。普通人雖然沒有如此天賦,但在循環(huán)結(jié)構(gòu)的加持下,也可以做同樣的事,甚至可

以是從

1加到任意自然數(shù),其操作如代碼

3.10所示。3.2.1while語句在構(gòu)思

while語句的代碼時,要明確循環(huán)的條件是什么,分清哪些工作是在循環(huán)之前要做好的預(yù)備工作,哪些是循環(huán)內(nèi)部要做的工作。下面就按照這個思路來分析代碼

3.10

是如何構(gòu)思完

成的。首先仍然是獲取程序的輸入,即累加的終止整數(shù),保存在變量

n

中。其次是核心的處理環(huán)節(jié),

這個環(huán)節(jié)要把加法操作重復(fù)很多遍,因此是一個循環(huán)結(jié)構(gòu)。循環(huán)條件即為當(dāng)前累加的整數(shù)沒有超過

終止整數(shù)n。但如何知道當(dāng)前累加的整數(shù)是多少呢?這時就需要在循環(huán)開始前預(yù)備一個變量,用來

跟蹤當(dāng)前正在累加的整數(shù),這就是變量n_loop,它的初始值應(yīng)該為

1,隨著循環(huán)的進(jìn)行而不斷遞增,

直到終止整數(shù)n。另外,還要準(zhǔn)備一個變量

result保存累加之后的結(jié)果,其初始值為

0。到此循環(huán)之

前的預(yù)備工作結(jié)束,之后開始構(gòu)造循環(huán)。因?yàn)檠h(huán)條件已經(jīng)明確,所以

while所在行即可明確寫出,

記得行尾要有冒號。循環(huán)體內(nèi)部做什么呢?每次循環(huán)都要將當(dāng)前的整數(shù)累加到result

變量中,即將

n_loop

累加到

result

中。最后不要遺忘

n_loop加

1,這樣下次循環(huán)

n_loop時才會是下一個自然數(shù),

同時循環(huán)條件也才會有為False的時候。到此循環(huán)體構(gòu)造完成。代碼的最后部分是輸出結(jié)果,這個

print()函數(shù)沒有縮進(jìn),不屬于

while語句。3.2.1while語句代碼

3.10

中的

while語句在執(zhí)行前即可明確知道循環(huán)的次數(shù),這種循環(huán)有時被稱為計(jì)數(shù)控制循

環(huán)(count-controlled)。還有的循環(huán)一定要重復(fù)到某個事件發(fā)生,預(yù)先不知道要循環(huán)多少次,這種循

環(huán)被稱為事件控制循環(huán)(event-controlled)。這就好比要背誦一篇課文,事先并不知道要背多少遍才

能背下來。循環(huán)條件是“沒背過”,只要條件為真就要一直背,直到背過了這件事發(fā)生為止3.2.1while語句2.事件控制循環(huán)代碼

3.11演示了事件控制循環(huán)。程序會以互動的方式詢問用戶心中的旅游目的地,用戶可以不

斷輸入自己向往的地點(diǎn),直到輸入“再見”為止。因?yàn)槌绦驘o法預(yù)知用戶會在第幾次循環(huán)中輸入“再

見”,所以代碼中的while循環(huán)無法預(yù)知循環(huán)次數(shù),while語句只是在等待一件事發(fā)生,那就是用戶

輸入的目的地信息不是某個地點(diǎn),而是“再見”。一旦此事發(fā)生,循環(huán)即結(jié)束。程序開頭部分先輸出一些提示信息,告知用戶如何與程序互動。3.2.1while語句2.事件控制循環(huán)程序預(yù)備了

3個變量,其中

list_msg用來保存最后的目的地清單,number用來記錄每個目的地

的順序編號,而

destination則是每次輸入的目的地。當(dāng)

destination是“再見”二字時while循環(huán)結(jié)束。

這里的“再見”就是所謂的哨兵值,它不是真正有意義的輸入,而是終止信號。程序執(zhí)行到此預(yù)備

工作完成,開始正式書寫while

語句部分。注意循環(huán)條件的寫法,既然事件控制循環(huán)是要等到一件

事情發(fā)生就結(jié)束,那么循環(huán)條件當(dāng)然是那件事沒有發(fā)生,所以循環(huán)條件是

destination不等于“再見”

二字。循環(huán)體有以下幾項(xiàng)工作:①構(gòu)造目的地清單,這是一個對字符串進(jìn)行的“累加”操作,每次

輸入的目的地和已經(jīng)轉(zhuǎn)換為字符串的序號銜接起來,被“累加”到目的地清單中。這里要清楚“+”

運(yùn)算對于字符串而言是首尾銜接。②記錄序號的變量number要遞增,循環(huán)體最后一項(xiàng)任務(wù)是再次要

求用戶輸入目的地,只有輸入目的地的工作出現(xiàn)在循環(huán)體內(nèi),程序運(yùn)行后才會不斷地從鍵盤上接收

目的地信息。3.2.1while語句代碼

3.11while語句示例:事件控制循環(huán)print("中國那么大,你不想去看看嗎?")print("請輸入你心中的目的地,一次一個,輸入再見結(jié)束。")list_msg=

""number=

1destination=input("請輸入目的地:")whiledestination

!=

"再見":list_msg+=str(number)+

destination

+

"

"number+=

1destination=input("請輸入目的地:")iflist_msg:#非空字符串轉(zhuǎn)換為

Trueprint("目的地:",list_msg)else:print("心中的目的地為什么不說出來呢")3.2.1while語句程序的最后部分要輸出目的地清單,在輸出之前要判斷一下

list_msg

是否是空字符串。如果用

戶與程序的第一次互動就輸入“再見”二字,一個目的地都沒提供,那么while

循環(huán)一次都沒被執(zhí)

行,此時

list_msg

為初始值,即空字符串。最后的輸出要根據(jù)

list_msg

是否為空分兩種情況討論。

當(dāng)

list_msg不為空時,相當(dāng)于

if的條件表達(dá)式為

True,則輸出list_msg

即可;如果

list_msg為空,

if

語句進(jìn)入

else分支,輸出替代的信息。代碼

3.11

的運(yùn)行結(jié)果如下。3.2.2for語句對于預(yù)先可明確次數(shù)的循環(huán),很多程序語言提供了另外一種循環(huán)結(jié)構(gòu),即

for

語句。Python

不例外,而且

Python

中的

for語句更加接近人類語言,使用起來很方便。1.對比

for

語句和

while

語句下面的代碼

3.12使用

for語句完成與代碼

3.10一樣的工作。為了便于對比這兩段代碼,特將代

3.10列在下面,讀者可仔細(xì)觀察兩段代碼的異同。代碼

3.12for語句示例:完成累加n=int(input("從

1加到多少?

"))result=

0fori

in

range(1,n+1):result+=

iprint("從

1加到",n,"的和是:",result)3.2.2for語句對于預(yù)先可明確次數(shù)的循環(huán),很多程序語言提供了另外一種循環(huán)結(jié)構(gòu),即

for

語句。Python

不例外,而且

Python

中的

for語句更加接近人類語言,使用起來很方便。1.對比

for

語句和

while

語句下面的代碼

3.12使用

for語句完成與代碼

3.10一樣的工作。為了便于對比這兩段代碼,特將代

3.10列在下面,讀者可仔細(xì)觀察兩段代碼的異同。3.2.2for語句總體來說,代碼

3.12

比代碼

3.10要簡短一些。代碼

3.12在循環(huán)之前只是預(yù)備了n與

result兩個

變量,沒有

n_loop,因此循環(huán)體中也無須每次對n_loop加

1。for語句的循環(huán)體很簡單,只有一行代

碼完成累加。但

for語句多了一個變量

i及

range()函數(shù),這應(yīng)該是理解

for語句的重點(diǎn)。3.2.2for語句2.解讀

for語句for語句常與

range()函數(shù)結(jié)合使用,因此先從

range()函數(shù)說起。它和

print()、input()函數(shù)一樣,

也是

Python

內(nèi)置的函數(shù)。range()函數(shù)的功能如其名稱暗示的一樣,會返回一定范圍內(nèi)的整數(shù),范圍

range()函數(shù)的兩個參數(shù)指定。例如,

代碼

3.12

中的“range(1,n+1)”,含義是從

1開始到n結(jié)束的

所有整數(shù),注意不包含

n+1。因此

range()函數(shù)返回的是一個整數(shù)序列,序列包含左邊界,不包含右邊界。這一點(diǎn)在代碼

3.13

中會觀察得更明顯。代碼

3.13

第一部分的

range(1,11)得到的是從

1

10

的整數(shù)序列,不包含右邊界

11。而且因?yàn)?/p>

print()函數(shù)的

end參數(shù)被設(shè)置為“;”,所以這

10個整數(shù)

在一行輸出,彼此以分號分隔,如代碼中的注釋所示。3.2.2for語句代碼

3.13

range()函數(shù)示例fori

in

range(1,11):print(i,end=";")

#1;2;3;4;5;6;7;8;9;10;print()fori

in

range(11):print(i,end=";")

#0;1;2;3;4;5;6;7;8;9;10;print()fori

in

range(1,11,2):print(i,end=";")

#1;3;5;7;9;print()fori

in

range(11,0,-2):print(i,end=";")

#11;9;7;5;3;1;3.2.2for語句另外,如果

range()函數(shù)括號內(nèi)只有一個參數(shù),則該參數(shù)為右邊界,此時左邊界為

0,如代碼第

二部分的

range(11),左邊界為

0

,11為右邊界,因此會得到從

0到

10共

11個整數(shù)。range()函數(shù)還

可以有第三個參數(shù),即步長。步長表示整數(shù)序列中相鄰兩項(xiàng)的間隔,默認(rèn)步長為1,可省略不寫。

當(dāng)步長不為

1

時,就要通過第三個參數(shù)指出步長值。例如,代碼

3.13

中第三部分的

range(1,11,2)

,

其含義是左邊界為1,右邊界為11,步長為2。因此得到的整數(shù)序列為“1;3;5;7;9;”,不含11。

步長可以是負(fù)整數(shù),只不過步長為負(fù)時,左邊界要大于右邊界??梢孕蜗蟮乩斫鉃樵谙聵?,一步

下幾個臺階由步長控制。因此代碼中的

range(11,0,-2)得到的整數(shù)序列從

11開始遞減,如代碼中的

注釋所示。3.2.2for語句理解了

range()函數(shù),再回過頭看代碼

3.12就容易了。for語句中有一個循環(huán)變量

i,其值要依次

range()函數(shù)得到的序列的每一個整數(shù)。因?yàn)榇a

3.12

中的“range(1,n+1)”得到的是

1到

n

的整數(shù),

所以第一次循環(huán)時

i

的值為

1,第二次循環(huán)時

i

的值為

2,以此類推,直到

i取值為

n。對于

for語句的循環(huán)變量,無須在

for語句之前提前定義它,只需在

for關(guān)鍵字后給循環(huán)變量起

個直觀的名稱,for語句會負(fù)責(zé)初始化循環(huán)變量并負(fù)責(zé)讓循環(huán)變量走遍序列中的每個值,因此也無須

在循環(huán)體中改變循環(huán)變量的值。這是

for語句顯著區(qū)別于

while語句的地方。至于循環(huán)變量的名稱也

未必是

i,任何符合

Python標(biāo)識符規(guī)范的名稱均可。3.2.2for語句3.使用

for語句遍歷字符串雖然

for語句經(jīng)常與

range()函數(shù)配合使用,但不意味著

for語句只能用來遍歷整數(shù)序列。事實(shí)上,

很多序列型的數(shù)據(jù)都可以使用

for語句來遍歷。例如,字符串是由字符構(gòu)成的序列,因此可以很方便

地使用

for語句來遍歷字符串。下面的代碼

3.14演示了使用

for語句輸出《山海經(jīng)》中的一段文字。這段文字極富想象力,充

滿了奇幻色彩。為了能有更好的觀感,在輸出

text

字符串中的每一個字符時,會判斷該字符是不是

句號。如果是句號,則輸出該字符后會換行;如果不是句號,則輸出該字符后不換行。換行與否由

print()函數(shù)的

end參數(shù)控制,該參數(shù)的默認(rèn)值即為換行。3.2.2for語句代碼

3.14

使用

for語句遍歷字符串text="有夏州之國。有蓋余之國。有神人,八首人面,虎身十尾,名曰天吳。"\"大荒之中,有山名曰鞠陵于天、東極、離瞀,日月所出。"\"有神名曰折丹,東方曰折,來風(fēng)曰俊,處東極以出入風(fēng)。"forletter

in

text:ifletter

==

"。":print(letter)else:print(letter,end="")3.2.3循環(huán)結(jié)構(gòu)的嵌套就像

if

語句可以嵌套一樣,循環(huán)結(jié)構(gòu)也可以嵌套。無論是

while語句還是

for語句都可以在循環(huán)

體內(nèi)再出現(xiàn)循環(huán)結(jié)構(gòu),從而形成嵌套循環(huán)。比較典型的是雙重循環(huán),在雙重循環(huán)中,外層循環(huán)與內(nèi)

層循環(huán)可以都是

while語句或

for語句,也可以是

while語句與

for語句混用。下面通過一個制訂背

單詞計(jì)劃的案例來演示雙重循環(huán)的使用方法。學(xué)習(xí)英語的一個重要任務(wù)是背單詞,而背單詞最重要的是持之以恒。不積跬步,無以至千里;

不積小流,無以成江海。無論目標(biāo)多么宏大,只要定好目標(biāo),將目標(biāo)的達(dá)成分解到每天,一小步、

一小步地向目標(biāo)前進(jìn)即可。那么如何將背單詞的目標(biāo)分解到每一天呢?假設(shè)一位大學(xué)生在入學(xué)之初

的英語詞匯量是

5000,他想在

3年內(nèi)將詞匯量提高到

10000。每

7天需要復(fù)習(xí)這一周背的單詞,每

30天需要復(fù)習(xí)一個月背的單詞。復(fù)習(xí)單詞的日子是沒有時間背新單詞的。每天要背多少新單詞才能

3年后達(dá)成目標(biāo)呢?3.2.3循環(huán)結(jié)構(gòu)的嵌套如果用數(shù)學(xué)的思維來求解這個問題,大概需要設(shè)未知數(shù)、列方程。但利用計(jì)算機(jī)來求解,可以

使用更“笨拙”、更簡單的思路,如代碼

3.15所示。這段代碼初看比較復(fù)雜,while語句、for語句

if

語句一應(yīng)俱全,還有模運(yùn)算及組合條件表達(dá)式,可以說是對前面所學(xué)的一個匯總。但它所體現(xiàn)

的解決問題的思路并不復(fù)雜,其基本思想是先從一個很小的單詞個數(shù)試起,如每天背

2個新單詞,

嘗試

3年后看能否達(dá)成目標(biāo)。如果不能,則改為每天背

3個新單詞,再重新嘗試

3年后看能否達(dá)成

目標(biāo),如果還不行,則繼續(xù)增加每天背新單詞的個數(shù)繼續(xù)嘗試,直到問題得到解決。代碼見3.15PART33.3循環(huán)結(jié)構(gòu):break和continue語句3.3.1break語句與循環(huán)結(jié)構(gòu)有關(guān)的語句除了while和

for語句,還有break和

continue語句。如果說

for和while

語句搭建了循環(huán)的框架,那么break和

continue語句則可在中途改變循環(huán)執(zhí)行的路線。3.3.1

break語句正如英文單詞本身的含義所暗示的,break語句將打斷其所在的循環(huán)結(jié)構(gòu),程序轉(zhuǎn)而執(zhí)行跟在循

環(huán)結(jié)構(gòu)之后的代碼。代碼

3.16將剛剛的背單詞案例修改為使用break語句而不是

done標(biāo)記變量來結(jié)

束外層循環(huán),注意代碼中的粗體部分。。3.3.1break語句代碼

3.16

背單詞案例(

break語句版)fortodayinrange(1,period+1):#內(nèi)層循環(huán)將嘗試每一天iftoday%

7

!=

0

and

today

%

30

!=

0:#如果不是復(fù)習(xí)日current+=words_each_day

#詞匯量增加words_each_dayifcurrent>=

target:#目標(biāo)達(dá)成breakelse:#目標(biāo)未達(dá)成words_each_day+=1#每日背的新單詞個數(shù)增加

1個msg="3

年內(nèi)的單詞量由"+str(start)

+

"提到"

+

str(target)

+

"每天需背"

\

+str(words_each_day)+

"個單詞"print(msg)start,target=5000,10000#起點(diǎn)、目標(biāo)period=

3

*

365#期限words_each_day=2#每天背的新單詞個數(shù)whileTrue:#僅從條件看這是死循環(huán),需要

break語句來打斷current=

start#每次外循環(huán)開始都要將

current還原為

start值3.3.1break語句這段代碼的while循環(huán)其條件是固定的,始終為

True。僅從條件來看,這個

while循環(huán)將永遠(yuǎn)循

環(huán)下去。為了避免其成為死循環(huán),循環(huán)的結(jié)束靠內(nèi)部的break語句。當(dāng)發(fā)現(xiàn)

current變量值不小于target

變量值時,背單詞的目標(biāo)可以達(dá)成。這時break語句發(fā)揮作用,打斷其所在的while循環(huán),程序轉(zhuǎn)而

執(zhí)行

while循環(huán)后面的代碼,即構(gòu)造

msg字符串代碼行。注意,如果break語句身處多重循環(huán),則它只能打斷其所在的那一層循環(huán)。例如,

代碼

3.17

中,

break語句屬于內(nèi)層循環(huán),因此其打斷的是內(nèi)層循環(huán),外層

for循環(huán)不會被break語句打斷。外層循

環(huán)重復(fù)

3遍,但內(nèi)層循環(huán)

range(1,11)雖然是生成

10個數(shù)的序列,但當(dāng)循環(huán)變量j

的值為

5時,內(nèi)層

for語句就會被強(qiáng)制打斷。因此內(nèi)層循環(huán)的

print()函數(shù)不會輸出j大于等于

5

的值,代碼實(shí)際的運(yùn)行)結(jié)果也證實(shí)了這一點(diǎn)。3.3.1break語句代碼

3.17

break打斷其所在的循環(huán)for

iin

range(3):forj

in

range(1,11):if

j

%

5

==

0:breakprint(j,end=";

")print()代碼

3.17

的運(yùn)行結(jié)果如下。外層循環(huán)仍然正常循環(huán)

3遍,因此結(jié)果有

3行。但每一行僅僅到

4,

j大于等于

5

的值是不可能被輸出的。3.3.2continue語句與break

語句完全打斷所在循環(huán)結(jié)構(gòu)的執(zhí)行不同,continue

語句僅僅打斷所在循環(huán)的本輪次執(zhí)行,

轉(zhuǎn)而開啟所在循環(huán)下一輪的執(zhí)行。如果對剛剛的代碼

3.17稍作改動,將break換為

continue,得到代

3.18,則輸出的效果就完全不同。仔細(xì)對比這兩段代碼的運(yùn)行結(jié)果,就可以看出continue語句和

break語句的不同之處。代碼

3.18continue打斷所在循環(huán)的本輪次執(zhí)行for

iin

range(3):forj

in

range(1,11):if

j

%

5

==

0:continueprint(j,end=";

")print()3.3.2continue語句與break

語句完全打斷所在循環(huán)結(jié)構(gòu)的執(zhí)行不同,continue

語句僅僅打斷所在循環(huán)的本輪次執(zhí)行,

轉(zhuǎn)而開啟所在循環(huán)下一輪的執(zhí)行。如果對剛剛的代碼

3.17稍作改動,將break換為

continue,得到代

3.18,則輸出的效果就完全不同。仔細(xì)對比這兩段代碼的運(yùn)行結(jié)果,就可以看出continue語句和

break語句的不同之處。代碼

3.18continue打斷所在循環(huán)的本輪次執(zhí)行for

iin

range(3):forj

in

range(1,11):if

j

%

5

==

0:continueprint(j,end=";

")print()3.3.2continue語句產(chǎn)生這樣的運(yùn)行結(jié)果是因?yàn)楫?dāng)內(nèi)層循環(huán)的循環(huán)變量j是

5時,if

語句條件為

True,continue語句

發(fā)揮作用,導(dǎo)致內(nèi)層循環(huán)的本輪次即j為

5這一輪被立即終止,轉(zhuǎn)而開啟j為

6

的輪次,內(nèi)層循環(huán)的

print()沒有機(jī)會輸出j為

5

的值。j為

10時是同樣的道理。3.3.3循環(huán)結(jié)構(gòu)的else分支Python

語言為循環(huán)結(jié)構(gòu)也提供了

else

分支,這是很多其他程序語言沒有的。因此無論是

while

語句還是

for語句均可在后面跟一個

else語句塊,往往能實(shí)現(xiàn)很巧妙的功能,來看一個例子。我國歷史悠久,地域廣闊,有很多名塔,如西安的大雁塔、小雁塔,山西應(yīng)縣的木塔,河北正

定的華塔、須彌塔,大理的千尋塔,開封的鐵塔,蘇州的虎丘塔,杭州的六和塔、雷峰塔等。這些

塔的建筑材料多種多樣,外觀各具特色,每一座塔的背后都有一段故事,具有很高的歷史、科技與

藝術(shù)價值。下面的代碼

3.19試圖收集盡可能多的名塔名稱,但為了保證信息的純粹性,一旦發(fā)現(xiàn)輸

入的名稱中不含“塔”字,程序?qū)⒘⒓唇K止收集過程。3.3.3循環(huán)結(jié)構(gòu)的else分支代碼

3.19

循環(huán)結(jié)構(gòu)的

else分支print("本程序收集中國的名塔信息,歡迎提供您所知道的塔名。")print("一次一塔,輸入“完”結(jié)束。")tower=input("塔名:")number=

1tower_list=

""whiletower

!=

"完":if

"塔"not

in

tower:print("混入非塔建筑,名塔收集過程異常終止!")breaktower_list+=str(number)

+

tower

+

";"number+=

1tower=input("塔名:")3.3.3循環(huán)結(jié)構(gòu)的else分支代碼

3.19

循環(huán)結(jié)構(gòu)的

else分支else:iftower_list:print("名塔收集過程順利結(jié)束,以下是名塔清單:")print(tower_list)else:print("名塔收集過程順利結(jié)束,但用戶沒有輸入有用信息。")print("歡迎再次提供名塔信息,再見!")3.3.3循環(huán)結(jié)構(gòu)的else分支仔細(xì)研讀這段代碼會發(fā)現(xiàn)其大致的結(jié)構(gòu)與代碼

3.11輸入旅游目的地的案例非常相似,都是通過

循環(huán)結(jié)構(gòu)不斷從鍵盤獲取信息,都設(shè)置了哨兵值來結(jié)束循環(huán),循環(huán)體都要進(jìn)行字符串的銜接與編號

的遞增工作。不同的是這段代碼的while語句擁有

else分支。下面是用戶正常輸入塔名并以約定的哨兵值“完”結(jié)束的情形下,程序的運(yùn)行結(jié)果如下。PART43.4pass語句3.4pass語句寫代碼時一般是先搭建好大的結(jié)構(gòu),一些代碼塊如果暫時沒有構(gòu)思好則可以在該位置寫上pass,

這樣可以避免因整個代碼結(jié)構(gòu)的不完整而導(dǎo)致無法運(yùn)行。從這個意義上來說,一處代碼塊的位置寫

了pass語句和什么都不寫,區(qū)別還是很大的。下面的代碼

3.20假設(shè)在編寫代碼

3.19時剛剛構(gòu)思好大框架,一些細(xì)節(jié)還沒有實(shí)現(xiàn)??梢钥吹皆?/p>

循環(huán)的

else分支中寫有pass語句,此時程序雖然不完整,但可以正常運(yùn)行。如果將pass去掉,則代

碼就無法運(yùn)行了。3.4pass語句代碼3.20pass語句示例print("本程序收集中國的名塔信息,歡迎提供您所知道的塔名。")print("一次一塔,輸入“完”結(jié)束。")tower=input("塔名:")tower_list=

""whiletower

!=

"完":tower=input("塔名:")#todo#檢驗(yàn)塔名是否合規(guī)#構(gòu)造塔名清單else:#輸出塔名清單passprint("歡迎再次提供名塔信息,再見!")PART53.5Python生態(tài)系統(tǒng)之random庫本節(jié)介紹

random庫。這也是一個

Python標(biāo)準(zhǔn)庫,這個庫中有很多有意思的隨機(jī)函數(shù),利用它

們可以讓程序模擬很多隨機(jī)事件。3.5.1隨機(jī)小數(shù)random庫中有兩個常用的生成隨機(jī)小數(shù)的函數(shù),一個是

random.random()函數(shù),能生成[0.0,1.0)

區(qū)間的隨機(jī)小數(shù);另一個是random.uniform()函數(shù),可以生成指定區(qū)間內(nèi)的隨機(jī)小數(shù)。1.random()函數(shù)因?yàn)槭巧晒潭▍^(qū)間內(nèi)的隨機(jī)小數(shù),所以

random()函數(shù)不需要參數(shù),但括號仍然必不可少。下

面的代碼

3.21調(diào)用

random庫的

random()函數(shù)

100次,生成

100個[0,1)區(qū)間的小數(shù),并把每個小數(shù)保

4位小數(shù)后再輸出。3.5Python生態(tài)系統(tǒng)之random庫代碼

3.21

random庫的

random()函數(shù)示例importrandomfori

in

range(1,101):num=random.random()

#random函數(shù)生成[0,1)之間的隨機(jī)小數(shù)num=round(num,4)print(num,end=";

")3.5.1隨機(jī)小數(shù)生成隨機(jī)整數(shù)常用的函數(shù)有randint()和

randrange()。1.randint()函數(shù)randint()函數(shù)的名稱是由random和

integer兩個單詞組合而成的,顧名思義,是生成隨機(jī)整數(shù),

而且需要提供兩個參數(shù)來指定范圍。需要注意的是,randint()函數(shù)生成的隨機(jī)整數(shù)是有可能等于左右

兩個邊界的。代碼

3.23演示了這一點(diǎn)。代碼

3.23

random庫的

randint()函數(shù)示例importrandomfori

in

range(1,101):print(random.randint(1,10),end=";")這段代碼會循環(huán)

100次,每次生成一個

1~10之間的整數(shù)。注意觀察代碼運(yùn)行生成的

100個隨

機(jī)整數(shù)中,既有左邊界

1,又有邊界

10。篇幅所限,下面的結(jié)果有省略。3.5.2隨機(jī)整數(shù)7;2;

8;

4;2;

2;

9;

8;

8;

8;

5;

9;

4;

1;

2;

10;

8;

7;

1;

9;2.randrange()函數(shù)randrange()函數(shù)的名稱是由random和

range組合而成的,這個名稱很好地體現(xiàn)了其功能。range()

函數(shù)的功能在學(xué)習(xí)

for語句時已經(jīng)介紹,它會根據(jù)左右邊界及步長值生成一個整數(shù)序列。有了這個序

列,在其中隨機(jī)挑一個就是

randrange()函數(shù)做的事情。因此

randrange()函數(shù)也有

3

個參數(shù),其含義

range()函數(shù)類似。下面看代碼

3.24

的演示。代碼

3.24

random庫的

randrange()函數(shù)示例importrandomfori

in

range(1,11):print(random.randrange(1,10,2),end=";")有了

range()函數(shù)的基礎(chǔ),上述代碼不難理解。代碼循環(huán)

10次,每次調(diào)用

randrange()函數(shù)生成一

個隨機(jī)整數(shù),這個整數(shù)一定是

1、3、5、7、9

中的一個。至于生成的隨機(jī)整數(shù)不會是

10

的原因也與

range()函數(shù)一樣。3.5.2隨機(jī)整數(shù)有時需要從全體中隨機(jī)抽取一個或多個樣本進(jìn)行分析,這時可以使用

choice()和

sample()函數(shù)1.choice()函數(shù)使用

choice()函數(shù)時只需提供一個參數(shù)表示全體,函數(shù)的返回值是被選中的某一個樣本。假設(shè)用

26個英文字母代表

26個學(xué)生,他們有幸可以向諸子百家中的重量級人物提問,但由誰

向誰提問是隨機(jī)的。代碼

3.25演示了使用

choice()函數(shù)模擬這個過程。代碼

3.25

random庫的

choice()函數(shù)示例importrandomfor

iin

range(3):lucky_guy=random.choice("abcdefghijklmnopqrstuvwxyz")master=random.choice("老孔墨孟莊荀孫")msg="請"+

lucky_guy

+

"向"

+master

+

"子提問。"print(msg)3.5.3隨機(jī)抽樣代碼循環(huán)

3次,每次從

26個學(xué)生中隨機(jī)抽取一位學(xué)生,從幾位大師中也隨機(jī)抽取一位大師,然

后由該幸運(yùn)兒向選中的大師提問。因?yàn)槊看纬槿∶鎸Φ娜w沒有變,所以有可能出現(xiàn)重復(fù)的情形,

即有可能多次抽取到同一個人。代碼

3.25

的運(yùn)行結(jié)果如下。3.5.3隨機(jī)抽樣請

y

向孔子提問。請

d

向莊子提問。請

c

向墨子提問。代碼循環(huán)

3次,每次從

26個學(xué)生中隨機(jī)抽取一位學(xué)生,從幾位大師中也隨機(jī)抽取一位大師,然

后由該幸運(yùn)兒向選中的大師提問。因?yàn)槊看纬槿∶鎸Φ娜w沒有變,所以有可能出現(xiàn)重復(fù)的情形,

即有可能多次抽取到同一個人。代碼

3.25

的運(yùn)行結(jié)果如下。3.5.3隨機(jī)抽樣請

y

向孔子提問。請

d

向莊子提問。請

c

向墨子提問。2.sample()函數(shù)與choice()函數(shù)不同的是,sample()函數(shù)可以抽取多個樣本,所以使用sample()函數(shù)要至少提供

兩個參數(shù)。第一個參數(shù)是全體,第二個參數(shù)指定從全體中抽取幾個樣本。需要注意的是,其返回值

是一個列表,列表中的元素是被抽中的多個樣本。列表也是一個序列型的容器,可以保存多個元素。

關(guān)于列表的知識會在第

5章中進(jìn)行介紹。代碼

3.26

與代碼

3.25

相比,將其中的一個

choice()函數(shù)換成了

sample()函數(shù),實(shí)現(xiàn)每次抽取

3

位學(xué)生,這

3位學(xué)生放在列表

lucky_guys

中。構(gòu)造最后的

msg字符串時,因?yàn)檫@里的

lucky_guys是

列表,所以要用

str()函數(shù)轉(zhuǎn)換為字符串后才可以和其他字符串銜接。3.5.3隨機(jī)抽樣代碼

3.26

random庫的

sample()函數(shù)示例importrandomfor

iin

range(3):lucky_guys=random.sample("abcdefghijklmnopqrstuvwxyz",3)master=random.choice("老孔墨孟莊荀孫")msg="請"+

str(lucky_guys)

+

"向"

+master

+

"子提問。"print(msg)3.5.3隨機(jī)抽樣如果想模擬生活中的洗牌效果,則可以使用

shuffle()函數(shù),它可以將一個序列就地打亂順序。例

如,在代碼

3.27

中,列表

poker

中有

4張牌,將

poker

列表交給

shuffle()函數(shù)后,shuffle()函數(shù)會將

列表中的元素打亂順序,因此再輸出poker時其內(nèi)的元素就是另外一種順序了。代碼

3.27

random庫的

shuffle()函數(shù)示例3.5.4洗牌importrandompoker=

["J","Q","K","A"]#列表returned_anything=random.shuffle(poker)#shuffle()函數(shù)沒有返回值print(poker)#元素順序已經(jīng)改變print(returned_anything)#變量值為

NonePART63.6小試牛刀3.6小試牛刀本章的小試牛刀環(huán)節(jié)將通過幾個案例集中演練選擇結(jié)構(gòu)、循環(huán)結(jié)構(gòu)的各種語句,展示如何利用

random庫中的函數(shù)來模擬隨機(jī)事件。3.6.1

計(jì)算人體

BMI體重是反映和衡量一個人健康狀況的重要標(biāo)志之一。過胖和過瘦都不利于健康,也不會給人以

健美感。大量統(tǒng)計(jì)數(shù)據(jù)表明,身高與體重的關(guān)系可以作為反映人體健康狀態(tài)的指標(biāo),這就是身體質(zhì)

量指數(shù)(BodyMassIndex,BMI

)。BMI是用體重值(單位是千克)除以身高值(單位是米)的平方得出的數(shù)字,根據(jù)

BMI

的大小

可以判斷一個人的體型是過瘦、正常還是肥胖。表

3.1所示是我國的

BMI參考標(biāo)準(zhǔn),接下來根據(jù)這

個標(biāo)準(zhǔn)構(gòu)造一個程序,從鍵盤獲取身高、體重,然后給出體型結(jié)論。3.6小試牛刀代碼3.28利用if語句完成了根據(jù)BMI值判斷體型的流程。為了使觀看效果更好,將計(jì)算得到的BMI保留了1位小數(shù),并在輸出結(jié)果的同時提示正常范圍是多少.(代碼見書63頁3.28)表3.1BMI參考標(biāo)準(zhǔn)BMI

分類參考標(biāo)準(zhǔn)相關(guān)疾病發(fā)病的危險性消瘦BMI<

18.5低,但其他疾病危險性增加正常18.5

≤BMI<24平均水平超重24

≤BMI<28增加肥胖28

≤BMI增加3.6.2伯努利試驗(yàn)不白努力中學(xué)學(xué)習(xí)概率的時候老師應(yīng)該都舉過拋擲硬幣的例子,歷史上還真有不少數(shù)學(xué)家認(rèn)真地將硬幣

拋擲過成千上萬次。表3.2

列出了歷史上一些數(shù)學(xué)家拋擲硬幣的數(shù)據(jù)。類似拋擲硬幣這種在同樣的

條件下重復(fù)地、相互獨(dú)立地進(jìn)行的隨機(jī)試驗(yàn)被稱為伯努利試驗(yàn)。(代碼見書64頁3.29)表3.2歷史上幾位數(shù)學(xué)家拋擲硬幣的數(shù)據(jù)試驗(yàn)者拋硬幣次數(shù)正面朝上的次數(shù)反面朝上的次數(shù)德

·摩根409220482044蒲豐404020481992費(fèi)勒1000049795021皮爾遜240001201211988羅曼諾夫斯基8064039699409413.6.3模擬布朗運(yùn)動分子熱運(yùn)動雖然是一種微觀運(yùn)動,但在顯微鏡下通過觀察懸浮在水中的花粉微粒可以感受到這

種運(yùn)動。懸浮微粒不停地做無規(guī)則運(yùn)動的現(xiàn)象叫作布朗運(yùn)動,因?yàn)樗侵参飳W(xué)家

R.布朗在1827

首先發(fā)現(xiàn)的。雖然沒有顯微鏡,但讓小海龜配合

random庫,即可實(shí)現(xiàn)小海龜在屏幕上無規(guī)則地“亂走”,從

而在屏幕上再現(xiàn)布朗運(yùn)動。代碼

3.30列出了具體細(xì)節(jié)。(代碼見書65頁3.30)3.6.4羊與汽車的距離美國有一個電視游戲節(jié)目叫

Let'sMakeaDeal,游戲的玩家面前有

3扇關(guān)閉的門,其中一扇門的

后面是汽車,另外兩扇門后面則各藏有一只山羊。如果玩家能選中后面有車的那扇門,則可贏得該

汽車。當(dāng)玩家選定某扇門但未開啟它時,主持人會開啟剩下兩扇門中的一扇,露出一只山羊。因?yàn)?/p>

主持人知曉答案,所以不會開錯門。山羊顯露后,主持人會問玩家要不要將自己的選擇換為另一扇

仍然關(guān)著的門。如果玩家是你,是選擇換門還是不換呢?換另一扇門會否增加贏得汽車的概率呢?

這個問題被稱為三門問題,也稱為蒙提

·霍爾問題,因?yàn)樵摴?jié)目的主持人是蒙提·霍爾(MontyHall)。3.6.4羊與汽車的距離這個問題一經(jīng)拋出,大家眾說紛紜。從普羅大眾到統(tǒng)計(jì)學(xué)家紛紛下場進(jìn)行評論。到底該不該換

門,真相如何呢?其實(shí)無須使用高深的數(shù)學(xué)進(jìn)行計(jì)算,只需讓這個游戲發(fā)生足夠多的次數(shù),看看是

堅(jiān)持不換門得到汽車的概率高,還是堅(jiān)持換門得到汽車的概率高就可以了。問題是現(xiàn)實(shí)世界讓游戲

發(fā)生足夠的多次是不現(xiàn)實(shí)的,因此使用

random庫模擬吧。假設(shè)玩家堅(jiān)持不換門,重復(fù)這個游戲

10000

次。由于他不換門,因此他贏的情形是一開始就選

中了有車的門。再讓另一個玩家堅(jiān)持換門,重復(fù)這個游戲

10000

次。這個玩家贏的情形是他一開始

沒有選中有車的門。根據(jù)這兩點(diǎn)來設(shè)計(jì)程序。首先要將游戲中現(xiàn)實(shí)世界的事物數(shù)字化。例如,3

門,不妨用

0、1、2

來代表。因?yàn)槠囀请S機(jī)放在某一個門后的,所以完全可以假設(shè)汽車是放在

2

號門后,這并不影響實(shí)驗(yàn)的模擬。如此就有了代碼

3.31

的實(shí)現(xiàn)方案,代碼中用

randint()函數(shù)來模擬

玩家的選擇。(代碼見書66頁3.31)3.6.5《少年中國說》案例進(jìn)階版在第

2章縱向輸出《少年中國說》段落的案例中,最后的效果圖左側(cè)有些空,可回看圖

2.1。如

果在左側(cè)靠下位置繪制一個長城的圖案,左側(cè)靠上位置繪制遠(yuǎn)山的輪廓,整個畫面不僅左右平衡,

而且圖文并茂,效果會更好。最終的效果如圖

3.2所示。下面就來完成這個設(shè)想。首先文字部分的輸出完全繼承第

2章案例中的代碼,無須改動。讀者可在第

2章代碼的基礎(chǔ)上

補(bǔ)充完成本案例。完整的代碼會比較長,為了敘述方便,可將繪圖的代碼分成

4個部分,分別是繪

制長城部分、繪制長城所在近山的褶皺、繪制近山的裝飾苔點(diǎn)、繪制遠(yuǎn)山輪廓。除長城外,后面3

個部分都會用到

random庫。3.6.5《少年中國說》案例進(jìn)階版1.繪制長城圖案長城圖案由兩個烽火臺和城墻組成,在繪制過程中小海龜要不斷前進(jìn)、轉(zhuǎn)向,循環(huán)往復(fù)。因此

可以使用循環(huán)結(jié)構(gòu)來繪制長城。代碼

3.32

展示了繪制左側(cè)第一個烽火臺,以及兩個烽火臺之間的一

段城墻。繪制時,小海龜?shù)慕嵌?、前進(jìn)的距離等都要參考整個繪圖窗體的坐標(biāo)系。窗體的中心為坐

標(biāo)原點(diǎn),寬

1000個單位,高

500個單位。因此窗體最上沿的縱坐標(biāo)為

250,最下沿的縱坐標(biāo)為-250,

最左沿的橫坐標(biāo)為-500,最右沿的橫坐標(biāo)為

500。明確了坐標(biāo),代碼中的位置坐標(biāo)就不難理解了。(代碼見書68頁3.32)3.6.5《少年中國說》案例進(jìn)階版2.繪制近山褶皺從左到右山體上會出現(xiàn)

5個褶皺,每個褶皺由若干條線段構(gòu)成。構(gòu)成褶皺的每條線段的長度、

角度都隨機(jī)產(chǎn)生,因此會用到

random庫。其中,

線段的角度是在垂直向下的方向上隨機(jī)向左右兩側(cè)

偏轉(zhuǎn),但因褶皺整體上是由左上朝右下行進(jìn)的,所以褶皺線段的左右偏轉(zhuǎn)幅度不能相等,向左側(cè)偏

轉(zhuǎn)的角度可能較小,向右側(cè)偏轉(zhuǎn)的角度可能較大。代碼

3.33

中設(shè)置的是在垂直向下即

270°的基礎(chǔ)

上,向左最多偏轉(zhuǎn)

10°,

而向右最多可偏轉(zhuǎn)

50°。另外,構(gòu)成同一個褶皺的多條線段彼此之間在銜接時,下一條線段會出現(xiàn)在上一條線段的2/3

處。因此一條線段繪制完成后,小海龜要后退

1/3

的距離,然后繪制下一條褶皺線段。如果小海龜?shù)目v坐標(biāo)已經(jīng)低于-200,意味著當(dāng)前褶皺已經(jīng)靠近窗體下沿,可以開始繪制下一

條褶皺了,因此記錄褶皺數(shù)量的

hill變量要加

1。當(dāng)

hill變量超過

5后,循環(huán)結(jié)束,5條褶皺繪制

完成。(代碼見書69頁3.33)3.6.5《少年中國說》案例進(jìn)階版3.繪制近山苔點(diǎn)為了增加山體效果,特繪制若干個裝飾苔點(diǎn)。中國的山水畫表現(xiàn)山體,講究皴擦點(diǎn)染,山體的

厚重、褶皺、植被等就在這筆墨的舞動間被表現(xiàn)得淋漓盡致。如果說前面繪制的褶皺是在模擬山水

畫的“皴”,那么繪制苔點(diǎn)就是在模擬山水畫的“點(diǎn)”了。代碼

3.34利用小海龜?shù)?/p>

dot()方法繪制

100個苔點(diǎn),問題的關(guān)鍵在于確定苔點(diǎn)的位置。為了

增加趣味性,苔點(diǎn)應(yīng)該比較隨意,因此使用隨

溫馨提示

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

評論

0/150

提交評論