版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 物業(yè)行業(yè)法規(guī)政策解讀-洞察分析
- 虛擬現(xiàn)實(shí)公共服務(wù)創(chuàng)新-洞察分析
- 微服務(wù)架構(gòu)下保護(hù)算法優(yōu)化-洞察分析
- 投資者保護(hù)機(jī)制完善-洞察分析
- 網(wǎng)絡(luò)安全人才培養(yǎng)-第12篇-洞察分析
- 新型船舶材料研究-洞察分析
- 藝術(shù)傳承與鄉(xiāng)村振興-洞察分析
- 消費(fèi)者健康意識提升策略-洞察分析
- 信息素在種間關(guān)系中的作用-洞察分析
- 網(wǎng)絡(luò)攻防技術(shù)與計(jì)算機(jī)安全應(yīng)對策略研究-洞察分析
- 裝飾工程各種安全技術(shù)操作規(guī)程
- 辦公樓裝修工程招標(biāo)文件
- 【自動駕駛技術(shù)發(fā)展文獻(xiàn)綜述4500字(論文)】
- 《孟子》精讀學(xué)習(xí)通章節(jié)答案期末考試題庫2023年
- –-重酒石酸去甲腎上腺素的合成
- 超深基坑工程施工關(guān)鍵技術(shù)
- 《基于課程標(biāo)準(zhǔn)的學(xué)歷案》讀書心得課件
- 中西醫(yī)結(jié)合-慢性胃炎-課件
- 2023學(xué)年完整公開課版法布爾簡介
- 供應(yīng)商大會品質(zhì)報告課件
- 管道安全檢查表
評論
0/150
提交評論