Python程序設(shè)計基礎(chǔ)(第2版)課件 第4章 流程控制及應(yīng)用_第1頁
Python程序設(shè)計基礎(chǔ)(第2版)課件 第4章 流程控制及應(yīng)用_第2頁
Python程序設(shè)計基礎(chǔ)(第2版)課件 第4章 流程控制及應(yīng)用_第3頁
Python程序設(shè)計基礎(chǔ)(第2版)課件 第4章 流程控制及應(yīng)用_第4頁
Python程序設(shè)計基礎(chǔ)(第2版)課件 第4章 流程控制及應(yīng)用_第5頁
已閱讀5頁,還剩109頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第4章流程控制及應(yīng)用分支結(jié)構(gòu)循環(huán)結(jié)構(gòu)異常處理算法及問題求解4.14.24.34.4學(xué)習(xí)引導(dǎo)…了解…理解…掌握…運用4.1分支結(jié)構(gòu)4.1分支結(jié)構(gòu)分支結(jié)構(gòu)是一種基本的控制結(jié)構(gòu)用于根據(jù)不同條件采取不同操作或執(zhí)行不同代碼塊。True表達式1表達式2表達式m語句塊1語句塊2語句塊mFalseFalseTrueTrueif…elif…else分支match語句條件表達式4.1.1if…elif…else分支Python用if…elif…else關(guān)鍵字或其組合來選擇要執(zhí)行的語句。分支語句的基本結(jié)構(gòu)如下:

if條件測試表達式

1:

語句塊

1

elif條件測試表達式

2:

語句塊

2

elif條件測試表達式

3:

語句塊

3

……

else:

語句塊

n4.1.1if…elif…else分支if…elif…else語句將整個區(qū)間分為若干個區(qū)間當(dāng)滿足其中某一個區(qū)間的條件時,一定不會再滿足后續(xù)的其他條件,程序即終止判定。

elseifelifelifelifelif語句塊5語句塊4語句塊3語句塊2語句塊1語句塊6if4.1.1if…elif…else分支

if條件測試表達式

1:

語句塊

1

elif條件測試表達式

2:

語句塊

2

elif條件測試表達式

3:

語句塊

3

……

else:

語句塊

n分支結(jié)構(gòu)關(guān)鍵字:if、elif和else是分支結(jié)構(gòu)的關(guān)鍵字分支結(jié)構(gòu)由1個if、0個或多個elif和1個或0個else組成。由這三個關(guān)鍵詞開始的語句最后以冒號結(jié)束。要求其后面滿足該條件時要執(zhí)行的語句塊縮進,同一組分支結(jié)構(gòu)里的每個關(guān)鍵詞必須要對齊。4.1.1if…elif…else分支

if條件測試表達式

1:

語句塊

1

elif條件測試表達式

2:

語句塊

2

elif條件測試表達式

3:

語句塊

3

……

else:

語句塊

n條件測試表達式:if和elif

子句后都有條件測試表達式當(dāng)表達式的值為真

(非0數(shù)字、非空對象或True)時執(zhí)行對應(yīng)的語句塊各分支后的條件互斥,只能滿足其中一個條件,一旦滿足其中一個條件,便不再進行后續(xù)分支語句的判定。else子句后面無條件測試表達式,直接以冒號結(jié)束,不滿足前面條件的其他情況都進入else分支。4.1百分制分數(shù)轉(zhuǎn)五分制實例說明:輸入一個整數(shù),當(dāng)輸入不在[0,100]

區(qū)間時輸出提示“Dataerror!”當(dāng)輸入滿足要求的前提下,用多分支結(jié)構(gòu)實現(xiàn)百分制轉(zhuǎn)五分制。轉(zhuǎn)換規(guī)則:根據(jù)分數(shù)所在區(qū)間[0,60)、[60,70)、[70,80)、[80,90)、[90,100],分別輸出字符“E”“D”“C”“B”“A”。思路:不同的條件下只會進入其中一個分支只需要在每個分支里改變變量的值退出分支語句后用一個print()函數(shù)進行輸出實例4.1百分制分數(shù)轉(zhuǎn)五分制

score

=

int(input())

if

score

>

100

or

score

<

0:

#不合理分數(shù)時為“Dataerror!”

result

=

'Dataerror!'

elif

score

>=

90:

#區(qū)間為90=<score<=100

result

=

'A'

elif

score

>=

80:

#區(qū)間為80=<score<90

result

=

'B'

elif

score

>=

70:

#區(qū)間為70=<score<80

result

=

'C'

elif

score

>=

60:

#區(qū)間為60=<score<70

result

=

'D'

else:

#區(qū)間為0=<score<60

result

=

'E'

print(result)實例4.1.1if…elif…else分支——二分支二分支方法:只使用if和else語句進行條件判斷。當(dāng)分支較多時,需要嵌套使用分支結(jié)構(gòu)。缺點:需嚴格控制不同級別的縮進;不利于閱讀。True表達式1表達式3語句塊n表達式2語句塊2語句塊1FalseFalseTrueTrue語句塊mFalse4.1.1if…elif…else分支——單分支單分支方法:所有條件都用if語句判定。缺點:需要判定每個if語句中的條件,降低效率并容易引入錯誤。不論前面是否已經(jīng)找到滿足條件的分支,后續(xù)所有if語句都會被執(zhí)行。4.1.2match語句match語句:一種強大的模式匹配工具用于簡化復(fù)雜的條件判斷,比傳統(tǒng)的if…elif…else語句更強大,可以匹配數(shù)據(jù)的結(jié)構(gòu)和類型,不僅限于簡單的值比較。match

變量:

case

模式

1:

語句塊

1

case

模式2:

語句塊2

case_:

語句塊

nmatch

變量:指定要匹配的對象。case

模式:每個case語句定義一個模式來匹配

match語句中的變量。_:通配符,表示沒有匹配到其他模式時執(zhí)行的代碼,相當(dāng)于else。最基本的用法是匹配具體的值,就像if…elif…else語句一樣。4.2HTTP錯誤狀態(tài)碼實例說明:HTTP狀態(tài)碼是用以表示網(wǎng)頁服務(wù)器HTTP響應(yīng)狀態(tài)的3位數(shù)字代碼。接收一個代表HTTP狀態(tài)碼的數(shù)字,根據(jù)400、401、403、408等數(shù)字代碼,分別提示出錯信息。思路:使用match語句對該數(shù)字進行模式匹配。使用case<值>來處理單個狀態(tài)碼,如case400使用case<值1>|<值2>將相似處理邏輯的狀態(tài)碼合并,如case401|403使用case_(通配符)捕獲所有未被以上條件匹配到的情況,作為默認響應(yīng)。實例4.2HTTP錯誤狀態(tài)碼 def

http_error(status):

match

status:

case

400:

return

"Badrequest"

#錯誤請求

case

401

|

403:

#可匹配多個條件

return

"Notallowed"

#未授權(quán)或禁止訪問該資源

case

404:

return

"Notfound"

#找不到請求的資源

case

408:

return

"RequestTimeout"

#請求超時

case_:

return

"Something'swrongwiththeinternet" print(http_error(400))

#Badrequest實例match語句 def

process_data(value):

"""

處理數(shù)據(jù)"""

match

value:

case

int():

#匹配整數(shù)

return

f"'{value}'是一個整數(shù)"

case

str():

#匹配字符串

return

f"'{value}'是一個字符串"

case

list():

#匹配列表

return

f"列表'{value}'的長度是'{len(value)}‘”

case_:

#匹配其他類型

return

"Unknowntype"

print(process_data(42))

#輸出:'42'是一個整數(shù) print(process_data("hello"))

#輸出:'hello'是一個字符串 print(process_data([1,

2,

3]))

#輸出:列表'[1,2,3]'的長度是'3'4.1.2

根據(jù)數(shù)據(jù)類型進行匹配:match語句 def

check_number(num):

"""判斷一個數(shù)是正數(shù)、負數(shù)還是零"""

match

num:

case

n

if

n

>

0:

return

"正數(shù)"

case

n

if

n

<

0:

return

"負數(shù)"

case

0:

return

"零"

print(check_number(10))

#輸出:正數(shù) print(check_number(-5))

#輸出:負數(shù) print(check_number(0))

#輸出:零4.1.2

在case語句中添加條件限制,匹配用if語句來指定的條件:4.1.3條件表達式對于只有兩個分支的程序,可以用如下所示的一條語句實現(xiàn),這種語句稱為條件表達式:

xif條件表達式elseyif…else將一條語句分成三部分,是一個三元操作符的條件表達式。對條件表達式求值:若為True,則計算if前面的表達式x

的值并返回其運算結(jié)果;若為False,則計算else后面表達式y(tǒng)

的值并返回其運算結(jié)果。條件表達式m,

n

=

map(int,

input().split())

#輸入空格分隔的兩整數(shù),切分后映射為整數(shù)賦值給m、nif

m

>

n:

#判斷m是否大于n

max_number

=

m

#如果m大于n,將m賦值給max_numberelse:

#如果m不大于n

max_number

=

n

#將n賦值給max_numberprint(max_number)

#輸出max_number4.1.3m,

n

=

map(int,

input().split())max_number

=

m

if

m

>

n

else

n#如果m>n為True,max_number=m,否則max_number=nprint(max_number)用分支結(jié)構(gòu)程序,將用戶輸入的兩個數(shù)中的較大者命名為max_number

并輸出:4.2循環(huán)結(jié)構(gòu)4.2循環(huán)結(jié)構(gòu)循環(huán)結(jié)構(gòu)可以把需要重復(fù)做的工作放在一個語句塊中反復(fù)執(zhí)行。既可以減少代碼行數(shù)、又可以簡化業(yè)務(wù)邏輯,提高程序的可讀性。for循環(huán):一般用于循環(huán)次數(shù)可確定的情況下,用于遍歷已知數(shù)量的元素,一般也被稱為遍歷循環(huán)。while循環(huán):一般用于循環(huán)次數(shù)不確定的情況下,用于根據(jù)某個條件反復(fù)執(zhí)行,直到條件不再滿足,也稱為條件循環(huán)語句。4.2.1for循環(huán)for語句可以依據(jù)可遍歷結(jié)構(gòu)中的子項,按順序進行迭代??杀闅v結(jié)構(gòu)包括:可迭代數(shù)據(jù)類型,如range()、字符串、列表和文件對象等。for循環(huán)變量in可迭代對象:

語句塊[else:][語句塊]程序執(zhí)行時,從可遍歷結(jié)構(gòu)中逐一提取元素,賦值給循環(huán)變量,每提取一個元素執(zhí)行一次語句塊中的所有語句,總的執(zhí)行次數(shù)由可遍歷結(jié)構(gòu)中元素的個數(shù)確定。else子句部分可以省略,它只在循環(huán)正常結(jié)束時被執(zhí)行(包含循環(huán)0次),如果跳出循環(huán)或結(jié)束程序,則不會執(zhí)行。4.2.1for循環(huán)——range類型range是一種數(shù)據(jù)類型,表示一個不可變的等差數(shù)列(算術(shù)級數(shù)),常用于for循環(huán)中。在僅控制循環(huán)次數(shù)或需要使用等差數(shù)列時,可以使用range()函數(shù)。

range(stop)

#0,1,2,3,4,…,stop

-

1。初值為

0,步長為

1

的等差數(shù)列range()函數(shù)的參數(shù)必須為整數(shù)。當(dāng)range()僅有一個整數(shù)參數(shù)時,可產(chǎn)生0,1,2,3,4,…stop-1,初值為0,步長為1,末項為該整數(shù)-1的等差數(shù)列。當(dāng)參數(shù)值小于等于0時,產(chǎn)生空序列。4.2.1for循環(huán)——range類型

range(start,stop[,step])

#start,start

+

step,start

+

2

*

step,…

步長為

step

的等差數(shù)列當(dāng)range()有

2個或3個整數(shù)參數(shù)時,可產(chǎn)生以start開始、步長為step、末項小于stop值的等差數(shù)列。如果start參數(shù)缺省,默認值為0;如果step參數(shù)缺省,默認值為1,step值可以為正數(shù)或負數(shù),但不可為0。 print(*(range(0,

40,

5)))

#05101520253035 print(*(range(0,

-5,

-1)))

#0-1-2-3-4 print(*(range(1,

11)))

#12345678910 print(*(range(1,

0)))

#步長為1,stop<start時,輸出''4.2.1for循環(huán)——range類型由于range采用惰性求值的方式產(chǎn)生數(shù)據(jù),使用print()函數(shù)并不能直接看到range數(shù)據(jù)的具體元素。輸出range

數(shù)據(jù)主要有以下三種方式:1.轉(zhuǎn)成列表或元組的形式輸出:print(list(range(n)))或print(tuple(range(n)))2.解包輸出:print(*(range(n)))3.結(jié)合for循環(huán)輸出 print(range(5))

#輸出range(0,5) print(list(range(5)))

#輸出[0,1,2,3,4] print(*range(5))

#01234 for

i

in

range(5): print(i,

end

=

'

')

#012344.2.1for循環(huán)——range()函數(shù)應(yīng)用 #計算等差數(shù)列和 my_sum

=

0

#設(shè)定初值為0,用于累加 for

i

in

range(5,

10):

#range()生成序列5,6,7,8,9,依次賦值給i

my_sum

=

my_sum

+

i

#每次循環(huán)將新的i值加到my_sum上 print(my_sum)

#輸出my_sum的值35

for循環(huán)中控制循環(huán)次數(shù)語法如下:

for<variable>inrange([start,]stop[,step]):

<語句塊>循環(huán)控制變量,經(jīng)常用i、j等表示每次循環(huán)從range()產(chǎn)生的數(shù)列中依次取一個值。4.2.1for循環(huán)——range類型 product

=

1

#設(shè)定初值為1,用于累加 for

i

in

range(5,

11,

2):

#range()生成序列5,7,9,依次賦值給i

product

=

product

*

i

#每次循環(huán)將新的i值乘到product上 print(product)

#輸出product的值315將累加語句修改為product=product*i

就可以計算前n項的積變量product的初值應(yīng)該賦值為1乘數(shù)i

的初值不可為0當(dāng)起始值start和步長step都為1時,程序的功能就是計算終值stop的階乘。4.2.1for循環(huán)——range()函數(shù)應(yīng)用 n

=

int(input())

#將輸入的字符轉(zhuǎn)成整型,10 print(sum(range(1,

n

+

1)))

#sum()函數(shù)可返回序列參數(shù)的元素的和,55

結(jié)合sum()函數(shù)求等差數(shù)列n項和將range()函數(shù)直接作為sum()函數(shù)的參數(shù),可以直接獲得range()函數(shù)所生成序列中全部元素的和。改變range()函數(shù)中start、stop、step的值,便可以計算不同等差數(shù)列中連續(xù)n項和了。 print(sum(range(50,

80,

5)))

#序列505560657075的和為3754.3計算麥粒數(shù)量實例說明:相傳國王要獎賞國際象棋的發(fā)明人,國王問他想要什么,他對國王說:請您在這張棋盤的第1

個小格里,賞給我1

粒麥子,在第2

個小格里給2

粒,第3

小格給4

粒,以后每一小格都比前一小格加一倍。請您把這樣擺滿棋盤上所有的64

格的麥粒就可以了。編程計算一共需要多少粒麥子。按照普通小麥的千粒重40g計算,問共需麥子約多少億噸?實例4.3計算麥粒數(shù)量def

calculate_chessboard_grains():

"""計算棋盤上的麥??倲?shù)"""

total_grains

=

0

#棋盤上的麥??倲?shù)初值

current_square

=

1

#當(dāng)前格子上的麥粒數(shù)

for

square

in

range(64):

#64個格子

total_grains

=

total_grains

+

current_square

#累加當(dāng)前格子上的麥粒數(shù)

current_square

=

current_square

*

2

#下一格麥粒數(shù)是當(dāng)前2倍

return

total_grains

#返回棋盤上的麥??倲?shù)total_grains

=

calculate_chessboard_grains()total_weight

=

total_grains

*

40/1000

*

1e-3

*

1e-3

*

1e-8print(f"共需{total_grains}

粒麥子。")

#共需18446744073709551615粒麥子print(f'總質(zhì)量為{total_weight:.2f}億噸')

#總質(zhì)量為7378.70億噸實例4.4判定素數(shù)實例說明:素數(shù)又稱為質(zhì)數(shù),一個大于1的自然數(shù),除了1和它自身外,不能被其他自然數(shù)整除的數(shù)叫作素數(shù);否則稱為合數(shù)(規(guī)定1既不是質(zhì)數(shù)也不是合數(shù))。請編寫程序判斷輸入的自然數(shù)是否為素數(shù)。思路:對于大于1的自然數(shù)n,可以遍歷從2到n-1

之間的數(shù)字,判斷其中是否存在這個數(shù)n的因子。若其中存在n的因子,則數(shù)n不是素數(shù)。若遍歷結(jié)束,未發(fā)現(xiàn)其因子存在,則數(shù)n為素數(shù)。實例4.4判定素數(shù)n

=

int(input('請輸入一個自然數(shù):'))

#輸入一個自然數(shù)if

n

<

2:

#自然數(shù)包括0和1,0和1以及負數(shù)都不是素數(shù)

print(f'{n}不是素數(shù)')for

i

in

range(2,

n):

#遍歷從2到n-1的數(shù)字

if

n

%

i

==

0:

#當(dāng)存在能被整除的數(shù)時,不是素數(shù)

print(f'{n}不是素數(shù)')

break

#確定不是素數(shù)后不需要繼續(xù)判定,略過后續(xù)語句,直接結(jié)束循環(huán)else:

#與for子句匹配,for循環(huán)中未遇到break語句時執(zhí)行此語句,i==2時也進入此分支

print(f'{n}是素數(shù)')實例4.4判定素數(shù)n

=

int(input('請輸入一個自然數(shù):'))

#輸入一個自然數(shù)if

n

<

2:

#0和1以及負數(shù)都不是素數(shù)

print(f'{n}不是素數(shù)')for

i

in

range(2,

int(n**0.5)+1):

#遍歷從2到int(n**0.5)的數(shù)字

if

n

%

i

==

0:

#當(dāng)存在能被整除的數(shù)時,不是素數(shù)

print(f'{n}不是素數(shù)')else:

#與for子句匹配,i==2時也進入此語句塊

print(f'{n}是素數(shù)')實例

4.5尋找水仙花數(shù)

實例4.5尋找水仙花數(shù)for

num

in

range(100,

1000):

#枚舉所有的三位數(shù),從100到999

result

=

0

#用于存儲累加計算結(jié)果,設(shè)初值為0

for

i

in

str(num):

#將num轉(zhuǎn)換為字符串,遍歷該數(shù)的每一位

result

=

result

+

int(i)**3

#將每位上的字符轉(zhuǎn)為整數(shù),計算每一位的立方和

if

result

==

num:

#判斷是否為水仙花數(shù)

print(f"{num}

是水仙花數(shù)")實例hundreds

=num//

100

#百位tens

=

(num//

10)

%

10

#十位ones

=num%

10

#個位整除和取模字符串遍歷4.6成績統(tǒng)計分析實例說明:現(xiàn)有一個讀文件切分得到的列表,為若干學(xué)生的成績,如scores_ls=['91.1748','81.64305','95.95105','60'],統(tǒng)計這些成績的平均值。思路:循環(huán)遍歷列表,在循環(huán)中將每個字符串成績用float()轉(zhuǎn)換后累加到總分,并對成績數(shù)量進行計數(shù)。循環(huán)結(jié)束后,用總分除以成績總數(shù),得出平均分。實例4.6成績統(tǒng)計分析實例scores_ls

=

['91.1748',

'81.64305',

'95.95105',

'60']scores_total

=

0

#總成績,初始值為0scores_count

=

0

#成績個數(shù),初始值為0

for

score

in

scores_ls:

#逐行讀取文件內(nèi)容

scores_total

=

scores_total

+

float(score)

#成績轉(zhuǎn)換為浮點數(shù)并累加到總成績

scores_count

=

scores_count

+

1

#成績個數(shù)加1average_score

=

scores_total

/

scores_count

#返回平均成績

print(f'平均成績:{average_score:.2f}')

#保留2位小數(shù),平均成績:82.194.2.2while循環(huán)for循環(huán)一般用于確定次數(shù)循環(huán)時使用,而在無法確定次數(shù)時,用while循環(huán)更加方便,它可以根據(jù)給定條件決定循環(huán)次數(shù)。while循環(huán)也可以嵌套使用,也允許while循環(huán)和for循環(huán)嵌套一起使用。 while

判斷條件:

語句塊判斷條件的返回值為布爾型,即True或False。當(dāng)判斷條件表達式的結(jié)果為True時,執(zhí)行while下面縮進部分語句塊中的全部語句,然后再次檢查判斷條件的值重復(fù)以上操作,直到判斷條件的結(jié)果為False

時結(jié)束循環(huán)。4.7計算圓周率

實例4.7計算圓周率實例def

calculate_pi(precision):

"""計算圓周率,直到最后一項小于指定的精度值"""

pi,

i,

sigh

=

0,

1,

1

#設(shè)定初值,i用于改變分母,sign用于改變符號

while

1

/

i

>=

precision:

#最末項大于等于指定精度值時執(zhí)行循環(huán)體中的語句

pi

=

pi

+

sign

*

1

/

i

#累加,每次循環(huán)加上最后一項

sign

=

-

sign

#每循環(huán)一次改變一次符號,實現(xiàn)正負項交替

i

=

i

+

2

#每個分母的數(shù)字相差2

return

pi

*

4

#公式是π/4,乘4得以π的計算值

precision

=

float(input("請輸入精度數(shù)值:"))

#輸入:1e-6print(calculate_pi(precision))

#輸出:3.141590653589692增加計算項數(shù)可以提高精度,但算法效率不高,計算時間較長。4.8分解質(zhì)因數(shù)實例說明:分解質(zhì)因數(shù)是指將一個正整數(shù)表示為若干質(zhì)數(shù)的乘積。例如,12=2×2×3,其中2和3是質(zhì)數(shù)。質(zhì)因數(shù)分解在數(shù)論、密碼學(xué)、計算機科學(xué)等領(lǐng)域都有廣泛應(yīng)用。思路:對于一個整數(shù)n,要將其分解為一系列質(zhì)數(shù)的乘積,可以從2開始,逐一嘗試所有可能的因數(shù)。實例4.8分解質(zhì)因數(shù)實例def

is_prime(n):

"""接受一個整數(shù)輸入,判定是否為質(zhì)數(shù)(素數(shù)),返回布爾值"""

if

n

<

2:

return

False

#0和1不是素數(shù)

for

i

in

range(2,

int(n

**

0.5)

+

1):

#保證效率

if

n

%

i

==

0:

return

False

else:

return

True

#for循環(huán)正常結(jié)束未遇到return時返回True

num

=

int(input())

#輸入一個整數(shù)for

j

in

range(2,

num

+

1):

#2開始遍歷到num

while

num

%

j

==

0

and

is_prime(j):

#如果j是num的因子且j是質(zhì)數(shù)

print(j,end='

')

#輸出當(dāng)前質(zhì)因數(shù)j

num

=

num

//

j

#縮小num規(guī)模4.2.3流程跳轉(zhuǎn)Python提供了continue

和break

關(guān)鍵字,置于循環(huán)結(jié)構(gòu)中的分支語句塊中,根據(jù)條件改變循環(huán),控制循環(huán)結(jié)構(gòu)。continue語句:跳過本次循環(huán)中continue后面剩余語句的執(zhí)行,提前進入下一次循環(huán)。4.9計算列表中的負數(shù)的平方和實例說明:一個列表中有若干數(shù)字,其中包含正數(shù)和負數(shù),編程計算列表中正數(shù)的平方和。思路:遍歷列表中的每個數(shù)字。在循環(huán)內(nèi),首先判斷當(dāng)前數(shù)字是否為負數(shù)如果數(shù)字是負數(shù),則使用continue關(guān)鍵字直接進入下一次循環(huán)如果不是負數(shù),則計算其平方并進行累加實例4.9計算列表中的負數(shù)的平方和實例def

sum_of_squares(numbers):

"""計算列表中所有正數(shù)的平方和,忽略負數(shù)"""

total

=

0

#設(shè)一個初值,用于保存平方和

for

number

in

numbers:

#遍歷列表中的每個元素

if

number

<

0:

#判斷是否為負數(shù)

continue

#如果是負數(shù),跳過本次循環(huán)

total

=

total

+

number

**

2

#計算平方和

return

total

#返回平方和

#主程序,示例調(diào)用numbers

=

[1,

2,

-3,

-4,

5]

#列表中包含正數(shù)和負數(shù)print(f"列表中所有正數(shù)的平方和是:{sum_of_squares(numbers)}")

#304.2.3流程跳轉(zhuǎn)break語句:結(jié)束循環(huán)作用:跳過當(dāng)前循環(huán)中未執(zhí)行的次數(shù),提前結(jié)束語句所在的循環(huán)。例如枚舉時,找到一個滿足條件的結(jié)果就終止循環(huán)。應(yīng)用:終止while循環(huán)。while關(guān)鍵字常用于構(gòu)造無限循環(huán),while后面加True或一個結(jié)果為True的表達式,使循環(huán)判斷條件永遠為True,此時循環(huán)可以無限地執(zhí)行下去。除非遇到break

或return語句才能終止。4.9計算列表中的負數(shù)的平方和實例def

calculate_pi(precision):

"""計算圓周率,直到最后一項小于指定的精度值"""

pi,

i,

sign

=

0,

1,

1

#設(shè)定初值,i用于改變分母,sign用于改變符號

while

True:

#構(gòu)造無限循環(huán),除非在循環(huán)體內(nèi)遇到break語句或return語句才能終止

if

1

/

i

<

1e-6:

#當(dāng)最后一項小于10–6時結(jié)束循環(huán)

break

#略過循環(huán)中未執(zhí)行的次數(shù),提前終止while循環(huán)

pi

=

pi

+

sign

*

1

/

i

#累加,每次循環(huán)加上最后一項

sign

=

-

sign

#每循環(huán)一次改變一次符號,實現(xiàn)正負項交替

i

=

i

+

2

#每個分母的數(shù)字相差2

return

pi

*

4

#公式是π/4,乘4得以π的計算值

precision

=

float(input("請輸入精度數(shù)值:"))print(calculate_pi(precision))4.2.3流程跳轉(zhuǎn)break只能提前結(jié)束當(dāng)前循環(huán)當(dāng)循環(huán)層數(shù)多于一層時,不能直接用break跳出多重循環(huán)??梢杂靡粋€變量做標(biāo)記,用break退出一重循環(huán)后,根據(jù)標(biāo)記變量的值決定是否繼續(xù)退出外層循環(huán)。4.3異常處理4.3異常處理異常:一個影響了程序正常執(zhí)行的事件。一般情況下,在Python無法正常處理程序時就會發(fā)生一個異常。在Python中,異常也是一個對象,表示一個錯誤。當(dāng)Python程序發(fā)生異常時,需要捕獲處理它,否則程序會終止執(zhí)行。語法錯誤邏輯錯誤運行時錯誤4.3.1程序中的錯誤——語法錯誤語法錯誤(SyntaxError)也稱解析錯誤,是指不遵循語言的語法結(jié)構(gòu)引起的錯誤,程序無法正常運行。語法錯誤屬于編譯階段的錯誤,一般是指由于程序語句、表達式、函數(shù)等存在書寫格式錯誤或語法規(guī)則上的錯誤。常見的語法錯誤包括:程序存在遺漏了冒號或括號等必要的符號、關(guān)鍵詞拼寫錯誤、縮進不正確、全角符號和空語句塊等。這種錯誤一般會在IDLE或其他IDE中會有明顯的錯誤提示。4.3.1程序中的錯誤——邏輯錯誤邏輯錯誤指程序可以正常運行,但其執(zhí)行結(jié)果與預(yù)期不符。存在邏輯錯誤的程序,從語法上來說是正確的,但會產(chǎn)生意外的輸出或結(jié)果,并不一定會被立即發(fā)現(xiàn)。邏輯錯誤的唯一表現(xiàn)就是錯誤的運行結(jié)果。常見的邏輯錯誤包括:運算符優(yōu)先級考慮不周、變量名使用不正確、語句塊縮進層次不對、在布爾表達式中出錯等。4.3.1程序中的錯誤——邏輯錯誤例:當(dāng)輸入的用戶名為"admin"或"root",且密碼為"asd*-+"

時,輸出登錄成功。username,

password

=

input().split()

#切分空格分隔的輸入,分別賦值if

username

==

'admin'or

username

==

'root'

and

password

==

'asd*-+':

print("登錄成功")這段程序沒有語法錯誤,但由于or的優(yōu)先級低于and,一旦or左邊結(jié)果為True,右邊會被短路,不做處理,直接輸出“登錄成功”。這里可以用括號改變優(yōu)先級或分成兩個if語句來寫,確保邏輯的正確性。4.3.1程序中的錯誤——邏輯錯誤username,

password

=

input().split()#確保邏輯正確if

(username

==

'admin'or

username

==

'root')

and

password

==

'asd*-+':print("登錄成功")

#或分兩個if語句進行判定username,

password

=

input().split()if

username

==

'admin'or

username

==

'root':

if

password

==

'asd*-+':

print("登錄成功")

4.3.1程序中的錯誤——運行時錯誤運行時錯誤(RuntimeError)指程序可以運行,但是在運行過程中遇到錯誤,導(dǎo)致程序意外退出。當(dāng)程序由于運行時錯誤而停止時,也稱程序崩潰,一般我們說的異常便是運行時錯誤,有時也會把所有錯誤都歸于異常。4.3.2異常

異常:在Python無法正常處理程序時或者說程序運行時候發(fā)生錯誤而沒被處理時就會發(fā)生一個異常。這些異常會被Python中的內(nèi)建異常類捕捉異常的類型有很多:SyntaxError、NameError

、TypeError、ValueError

等異常處理:在程序設(shè)計中,可以編寫特定的代碼,專門用于捕捉異常,如果捕捉到某類異常,程序就執(zhí)行另外一段代碼,使程序能夠正確運行,這種處理方法就是異常處理。4.3.3try…except子句在Python中,可以使用try、except、else和finally這幾個關(guān)鍵詞來組成一個包容性很好的程序,通過捕捉和處理異常,加強程序的健壯性。用try

可以檢測語句塊中的錯誤,從而讓except語句捕獲異常信息并處理。try…except語法如下:4.3.3try…except子句try:

<語句塊1>except<異常名稱1>:

<語句塊2>[except<異常名稱2>:

<語句塊3>][else:<語句塊4>][finally:<語句塊5>]程序首先執(zhí)行try與except之間的語句塊如果未發(fā)生異常,忽略各except下面的語句塊,直接執(zhí)行else或以后的程序語句。如果發(fā)生異常,且異常與某個except后面的錯誤類型相符,則執(zhí)行該except后面的語句塊,可以是錯誤信息或者其他的可執(zhí)行語句。try:

<語句塊1>except<異常名稱1>:

<語句塊2>[except<異常名稱2>:

<語句塊3>][else:<語句塊4>][finally:<語句塊5>]4.3.3try…except子句except語句和finally語句都不是必須的,但是二者必須要有一個,否則就沒有try的意義了。except語句可以有多個,分別用于處理不同類型的異常,但程序只能執(zhí)行到其中一個。Python會按except語句的順序,依次匹配指定的異常,如果異常已經(jīng)處理就不會再進入后面的except語句。如果try中的異常沒有在except中被指出,那么系統(tǒng)將會拋出默認錯誤代碼,并且終止程序。try:

<語句塊1>except<異常名稱1>:

<語句塊2>[except<異常名稱2>:

<語句塊3>][else:<語句塊4>][finally:<語句塊5>]4.3.3try…except子句finally放在最后,其內(nèi)容通常是做一些后續(xù)的處理,比如關(guān)閉文件、資源釋放之類的操作。finally語句塊是無論如何都要執(zhí)行的,即使拋出默認錯誤,或是前面的語句中出現(xiàn)了return,都會將finally語句執(zhí)行完,再拋出錯誤代碼,或是執(zhí)行前面的return語句。這個方法在某些必須要結(jié)束的操作中頗為有用,如釋放文件句柄,或釋放內(nèi)存空間等。4.3.3try…except子句——常見異常Python允許在一個程序里同時對多類異常進行捕捉,觸發(fā)哪個異常就執(zhí)行哪個異常對應(yīng)的語句。Python內(nèi)置的"Exception"類可以捕捉到所有內(nèi)置的、非系統(tǒng)退出的異常,以及所有用戶定義的異常。以下是Python中常見的異常名稱及其描述:異常名稱描述異常名稱描述Exception

常規(guī)異常的基類,可以捕獲任意異常SystemError

一般的解釋器系統(tǒng)錯誤SyntaxError語法錯誤IndentationError

縮進錯誤(代碼沒有正確對齊)NameError

未聲明/未初始化的對象(沒有屬性)ValueError

傳入無效的參數(shù),或傳入一個調(diào)用者不期望的值,即使值的類型正確4.3.3try…except子句——常見異常異常名稱描述異常名稱描述ImportError

導(dǎo)入模塊/對象失?。窂絾栴}或名稱錯誤)IndexError

索引超出序列邊界,如

x只有

10個元素,序號為

0-9,程序中卻試圖訪問

x[10]ModuleNotFoundError模塊不存在KeyError

映射中沒有這個鍵(試圖訪問字典里不存在的鍵)ZeroDivisionError除(或取模)零TypeError對類型無效的操作OverflowError

數(shù)字運算超出最大限制TabErrorTab和空格混用AttributeError對象沒有這個屬性RuntimeError一般的運行時錯誤4.10簡單計算器實例說明:接受用戶任意輸入兩個數(shù)字和運算符號,輸出其加、減、乘、除的結(jié)果,并輸出“感謝使用計算器!”注意:

0不能做除數(shù),所以當(dāng)?shù)诙€數(shù)字為0時,程序要能夠?qū)Ξ惓]斎脒M行處理,使程序不至于因除零異常而崩潰。當(dāng)用戶在輸入數(shù)字時輸入了非數(shù)字字符,或是在輸入運算符號時,輸入了除“+、-、*、/”以外的符號時,應(yīng)該給出合適的處理。實例4.10簡單計算器思路:try語句塊中放置可能會觸發(fā)異常的代碼。如果用戶輸入如字母之類的非數(shù)字,這里可能會觸發(fā)ValueError。except語句塊中,使用ValueError

處理用戶輸入非數(shù)字或輸入無效操作符的情況;ZeroDivisionError

處理用戶除以零的情況。else語句塊放沒有觸發(fā)異常時的處理,打印計算結(jié)果。finally語句塊輸出一條感謝信息,表示程序的結(jié)束。實例4.10簡單計算器實例try:

num1

=

float(input("請輸入第一個數(shù)字:"))

#獲取用戶輸入

num2

=

float(input("請輸入第二個數(shù)字:"))

operation

=

input("請選擇操作(+,-,*,/):")

if

operation

==

"+":

#根據(jù)操作符執(zhí)行計算

result

=

num1

+

num2

(其他運算符同理,此處省略)

elifoperation==

"/":

result

=

num1

/

num2

#可能出現(xiàn)除以零的情況

else:

raise

ValueError("無效的操作符")

#手動觸發(fā)異常(接下頁)4.10簡單計算器實例(續(xù)上頁)except

ValueError

asve:

#處理用戶輸入非數(shù)字的異常

print(f"輸入錯誤:{ve}")except

ZeroDivisionError:

#處理除以零的異常

print("錯誤:不能除以零")else:

#如果沒有異常,輸出計算結(jié)果

print(f"結(jié)果:{num1}

{operation}

{num2}={result}")finally:

#無論是否發(fā)生異常,都執(zhí)行以下代碼

print("感謝使用計算器!")4.3.3try…except子句不能過于依賴異常檢測應(yīng)首先盡可能排除語法錯誤與邏輯錯誤,防御性方式編碼比捕捉異常方式更好,能夠提升性能,使程序更健壯。不要試圖用try語句解決所有問題,這將會極大地降低程序的性能。只有在錯誤發(fā)生的條件無法預(yù)知的情況下,才使用try...except進行處理。代碼可讀性變差,且容易隱藏錯誤。try語句塊的體積越大,期望之外的異常就越容易被觸發(fā),越容易隱藏真正的錯誤,從而帶來嚴重后果。要盡量減少try/except語句塊中的代碼量。4.4

算法及問題求解4.4.1枚舉算法枚舉算法,又稱窮舉法,是一種暴力搜索算法核心思想:通過遍歷所有可能的解,從中找到滿足問題要求的解。適用情況:問題規(guī)模較小或者解空間有限的情況,因為隨著問題規(guī)模的增大,計算量會呈指數(shù)增長。基本步驟:確定解空間,確定所有可能的解的集合;遍歷解空間,通過遍歷所有的可能解,檢查這些解是否滿足問題的要求;篩選解,對于每一個可能的解,判斷其是否符合條件,如果符合則記錄下來;輸出結(jié)果,最終輸出符合條件的解,或者輸出符合條件的最優(yōu)解。4.11百錢買百雞實例說明:用100文錢買100只雞其中,公雞5文錢1只,母雞3文錢1只,小雞1文錢3只。問如何買公雞、母雞、小雞,使得總數(shù)為100只,且總花費為100文。思路:0<雞的數(shù)量<100;雞的總數(shù)和錢的總數(shù)都為100;小雞數(shù)量是3的倍數(shù)。列舉所有公雞、母雞、小雞數(shù)量的可能組合,計算總錢數(shù),總數(shù)量、總錢數(shù)都是100的滿足條件。實例4.11百錢買百雞步驟:確定枚舉范圍,公雞、母雞和小雞的數(shù)量必須是非負整數(shù)且不大于100。確定枚舉解空間,逐一枚舉公雞和母雞的數(shù)量,通過約束條件計算小雞的數(shù)量,并驗證是否滿足總花費為100文的條件。篩選合法解,對于每一種公雞和母雞的組合,計算相應(yīng)的小雞數(shù)量,并判斷是否滿足條件。輸出合法解。實例4.11百錢買百雞實例for

cock

in

range(1,

100):

#公雞數(shù)量不為0且小于100

for

hen

in

range(1,

100):

#母雞數(shù)量不為0且小于100

for

chicken

in

range(3,

100,

3):

#小雞數(shù)量大于0小于100且是3的倍數(shù)

#雞的總數(shù)為100,錢的總數(shù)為100,小雞數(shù)量是3的整數(shù)倍

if

cock

+

hen

+

chicken

==

100

and

5

*

cock

+

3

*

hen

+

chicken

//

3

==

100:

print(cock,

hen,

chicken)

#遇到滿足條件的數(shù)字組合就輸出內(nèi)層循環(huán)要執(zhí)行多少次?100*100*33=33萬次4.11百錢買百雞實例for

cock

in

range(1,

20):

#公雞數(shù)量不超過20

for

hen

in

range(1,

33):

#母雞數(shù)量不超過33

chicken

=

100

-

cock

-

hen

#小雞數(shù)量可由公雞和母雞數(shù)量計算得到

if

chicken

%

3

==

0

and

5

*

cock

+

3

*

hen

+

chicken

//

3

==

100:

print(cock,

hen,

chicken)優(yōu)化:當(dāng)公雞和母雞數(shù)量x,y確定的情況下,小雞的數(shù)量z可由100–x–y計算,且小雞數(shù)量必須為3的倍數(shù),可以減少一些無效的枚舉、縮小解空間。公雞5文一只,最大數(shù)量不會超過20

只,同理,母雞不能超過33

只內(nèi)層循環(huán)要執(zhí)行多少次?19*32=6084.4.1枚舉算法枚舉算法通常邏輯簡單,容易實現(xiàn)和理解。如果解存在,枚舉算法最終一定能找到正確的解,因為它會遍歷所有可能的情況。缺點:效率低。不適合大規(guī)模問題,當(dāng)解空間非常大時,枚舉算法不可行,需要花費非常多的時間尋找解。優(yōu)點:在小規(guī)模問題上非常有效。廣泛應(yīng)用于各種組合、排列、優(yōu)化問題中:組合優(yōu)化問題,如背包問題、旅行商問題等,其中需要找到最優(yōu)解。搜索問題,如數(shù)獨、八皇后問題等,枚舉所有可能的解,找到符合條件的解。暴力密碼破解,典型的枚舉算法應(yīng)用,嘗試所有可能的密碼組合,找到正確密碼。數(shù)論問題,包括質(zhì)數(shù)判定、因數(shù)分解等問題。排列組合問題,如生成排列、組合、子集等。4.12尋找完全數(shù)實例說明:一個完全數(shù)是指一個正整數(shù)的所有真因數(shù),即除了它本身以外的所有因數(shù)之和等于這個數(shù)本身。例如,6的真因數(shù)(1、2、3)的和為6,所以6是完全數(shù);28的真因數(shù)(1、2、4、7、14)的和也是28,所以28也是完全數(shù)。編寫一個程序,找到指定范圍內(nèi)的所有完全數(shù)。思路:對于一個數(shù)n,它的真因數(shù)是所有比n小且能整除n的數(shù)??梢酝ㄟ^枚舉n的所有可能因數(shù)來計算它們的和是否等于n。實例4.12尋找完全數(shù)步驟:枚舉:遍歷給定范圍內(nèi)的每個正整數(shù)。求真因數(shù):對于每個數(shù)n,找到它的所有真因數(shù)。計算因數(shù)和:將這些因數(shù)相加,判斷是否等于n。輸出結(jié)果:如果是完全數(shù),輸出這個數(shù)。實例4.12尋找完全數(shù)實例def

is_perfect_number(n):

#判斷一個數(shù)是否為完全數(shù)

sum_of_divisors

=

0

#求n的真因數(shù)和

for

i

in

range(1,

n):

#遍歷1到n-1,找出所有能整除n的數(shù)

if

n

%

i

==

0:

sum_of_divisors

+=

i

return

sum_of_divisors

==

n

#判斷真因數(shù)和是否等于n,返回布爾值

num

=

10000

#示例調(diào)用:尋找1到10000范圍內(nèi)的完全數(shù)for

n

in

range(1,

num

+

1):

#遍歷1到num范圍內(nèi)的每個數(shù)

if

is_perfect_number(n):

#如果返回值為True

print(n)實例4.12尋找完全數(shù)

4.12尋找完全數(shù)實例def

is_perfect_number_optimized(n):

"""

判斷一個數(shù)是否為完全數(shù),只需遍歷1到sqrt(n)的范圍,減少不必要的計算"""

if

n

<

2:

return

False

sum_of_divisors

=

1

#因數(shù)1一定是任何數(shù)的因數(shù)

for

i

in

range(2,

int(n**0.5)

+

1):

#遍歷2到sqrt(n),同時加上配對的因數(shù)n//i

if

n

%

i

==

0:

sum_of_diviso

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論