2020-07-06 Python學(xué)習(xí)筆記17 循環(huán)復(fù)習(xí)

一些關(guān)于自己學(xué)習(xí)Python的經(jīng)歷的內(nèi)容,遇到的問題和思考等,方便以后查詢和復(fù)習(xí)。

聲明:本人學(xué)習(xí)是在扇貝編程通過網(wǎng)絡(luò)學(xué)習(xí)的,相關(guān)的知識(shí)、案例來源于扇貝編程。如果使用請(qǐng)說明來源。

for循環(huán)和while循環(huán)辨別

相同點(diǎn):

它倆最大的相同點(diǎn)是都是循環(huán),且都有循環(huán)體和縮進(jìn)??s進(jìn)是 Python 中用來表示層級(jí)關(guān)系的,非常的重要,縮進(jìn)錯(cuò)誤會(huì)導(dǎo)致代碼運(yùn)行結(jié)果不符合預(yù)期甚至報(bào)錯(cuò),這里再強(qiáng)調(diào)一下。

不同點(diǎn):

它倆最大的不同點(diǎn)在于循環(huán)次數(shù)是否確定。我們?cè)賮砘貞浺幌聝煞N循環(huán)的停止條件:while 循環(huán) 是在條件不滿足時(shí)停止循環(huán)。for 循環(huán) 是遍歷完整個(gè)序列的元素就停止循環(huán)。

因此,while 循環(huán) 更適合循環(huán)次數(shù)不確定的情況,而 for 循環(huán) 更適合循環(huán)次數(shù)確定的情況。

Break和continue比較

相同:

break 和 continue 它倆都只能用于循環(huán)內(nèi),且都是用于跳過循環(huán)。

不同點(diǎn)

所以 break 和 continue 語句的區(qū)別就是:break 語句用于在特定條件下 結(jié)束循環(huán),continue 語句用于在特定條件下 跳過當(dāng)前循環(huán)體中的剩余語句,繼續(xù)進(jìn)行下一輪循環(huán)。

練習(xí):輸入密碼

小貝用循環(huán)寫了個(gè)密碼檢測器,總共有 3 次試錯(cuò)機(jī)會(huì)。但小貝發(fā)現(xiàn),不管輸入的密碼正確與否,都要輸 3 遍才行。正確的做法應(yīng)該在密碼正確時(shí)結(jié)束。你能幫小貝解決這個(gè)問題嗎?

i = 0

while i < 3:

? i = i + 1? #這個(gè)可以放在這里

? # input() 函數(shù)可以獲取用戶輸入的字符串

? password = input('請(qǐng)輸入密碼')

? i = i + 1? #這個(gè)也可以放在這里

? if password == '520':

? ? print('密碼正確')

? ? break

? ? i = i + 1? #這個(gè)不不不不可以放在這里,否則輸入不正確的時(shí)候,永遠(yuǎn)還有三次機(jī)會(huì),因?yàn)閕一直是等于0 ,這里的賦值,不會(huì)用到else中。

? else:

print('密碼錯(cuò)誤,你還有' + str(3-i) + '次機(jī)會(huì)')

zip()函數(shù)

zip() 函數(shù)和range()結(jié)合使用,可以同時(shí)遍歷多個(gè)列表。(range()和for循環(huán)也能一起使用,遍歷)

例子:

names = ["吳承恩", "羅貫中", "施耐庵", "曹雪芹"]

books = ["西游記", "三國演義", "水滸傳", "紅樓夢(mèng)"]

for name, book in zip(names, books):

? print(book + '的作者是' + name)

# 輸出:

# 西游記的作者是吳承恩

# 三國演義的作者是羅貫中

# 水滸傳的作者是施耐庵

# 紅樓夢(mèng)的作者是曹雪芹

zip()函數(shù)返回結(jié)果是元組,需要用list改成列表,列表的元素是元組。

names = ["吳承恩", "羅貫中", "施耐庵", "曹雪芹"]

books = ["西游記", "三國演義", "水滸傳", "紅樓夢(mèng)"]

name_and_book = zip(names, books)

print(list(name_and_book))

# 輸出:[('吳承恩', '西游記'), ('羅貫中', '三國演義'), ('施耐庵', '水滸傳'), ('曹雪芹', '紅樓夢(mèng)')]

通過 list() 函數(shù)轉(zhuǎn)換后可以看到,它里面的元素是一個(gè)個(gè)元組。name, book 這樣用逗號(hào)分隔開的寫法可以獲取到元組中對(duì)應(yīng)的元素。這里其實(shí)又解鎖了元組的一個(gè)新知識(shí),可以用逗號(hào)分隔開的變量獲取元組里的各個(gè)元素。

# 3 個(gè)元素也同樣可以

a, b, c = ('我', '愛', 'Python')

print('a =', a)

print('b =', b)

print('c =', c)

# 輸出:

# a = 我

# b = 愛

# c = Pytho

names = ["吳承恩", "羅貫中", "施耐庵", "曹雪芹", "小貝"]

books = ["西游記", "三國演義", "水滸傳", "紅樓夢(mèng)"]

for name, book in zip(names, books):

? print(book + '的作者是' + name)

# 輸出:

# 西游記的作者是吳承恩

# 三國演義的作者是羅貫中

# 水滸傳的作者是施耐庵

# 紅樓夢(mèng)的作者是曹雪芹

可以看到,老師只給 names 列表添加了一個(gè)元素,結(jié)果和之前還是一樣的。因此結(jié)論是:當(dāng)用 zip() 函數(shù)同時(shí)遍歷兩個(gè)列表時(shí),如果兩個(gè)列表長度不一樣,遍歷次數(shù)以長度短的列表長度為準(zhǔn)。

練習(xí):遍歷兩個(gè)列表

左青龍

右白虎

前朱雀

后玄武

directions = ['左', '右', '前', '后']

animals = ['青龍', '白虎', '朱雀', '玄武']

for direction, animal in zip(directions, animals):

? print(direction + animal)

最后一行改成,號(hào)連接的話,連個(gè)部分之間是有空格的。

Print(direction, animal) 結(jié)果是 左 青龍

enumerate() 函數(shù)

老師還想給你介紹一個(gè)和新的列表相關(guān)的函數(shù)——enumerate() 函數(shù)。

enumerate,這個(gè)單詞是“列舉、枚舉”的意思。enumerate() 函數(shù)的用法很簡單,它的作用是同時(shí)給出序列的元素索引和元素。你看完下面這個(gè)例子你就明白是什么意思了:

names = ["吳承恩", "羅貫中", "施耐庵", "曹雪芹"]

for index, item in enumerate(names):

? print(index, item)

# 輸出:

# 0 吳承恩

# 1 羅貫中

# 2 施耐庵

# 3 曹雪芹

可以看到,index 是列表中元素的索引,item 是列表中對(duì)應(yīng)的元素。寫法是不是和 zip() 函數(shù)結(jié)合的 for 循環(huán)很像?我想你應(yīng)該猜出 enumerate() 函數(shù)的返回值長啥樣了吧,我們來驗(yàn)證一下:

names = ["吳承恩", "羅貫中", "施耐庵", "曹雪芹"]

print(list(enumerate(names)))

# 輸出:[(0, '吳承恩'), (1, '羅貫中'), (2, '施耐庵'), (3, '曹雪芹')]

enumerate() 函數(shù)返回值是 enumerate 類型,zip() 函數(shù)返回值是 zip 類型,都需要用 list() 函數(shù)轉(zhuǎn)換

練習(xí):報(bào)數(shù)程序

在沒有學(xué) enumerate() 函數(shù)之前,小貝寫了一個(gè)報(bào)數(shù)的程序。現(xiàn)在你掌握了 enumerate() 函數(shù),快來幫小貝用 enumerate() 函數(shù)改進(jìn)一下代碼吧!

初始程序:

names = ['小貝', '聞聞', '幫主']

index = 1

for item in names:

? print(item + str(index))

? index += 1

修改之后

names = ['小貝', '聞聞', '幫主']

for index, item in enumerate(names): #最初把index寫在后面,結(jié)果報(bào)錯(cuò)了。因?yàn)榇蛴〉臅r(shí)候,索引是打印在后面的,所以我這里也寫在后面。

但是enumerate在提前列表的元素和索引時(shí),只能是索引在前,元素在后。

? print(item + str(index + 1))

練習(xí):密碼破解

網(wǎng)絡(luò)攻防聽上去很高端、很難懂,但有些概念其實(shí)很簡單。比如密碼破解,最簡單的方式就是暴力破解,也就是窮舉法。人工手動(dòng)地去一個(gè)一個(gè)試密碼既耗時(shí)又耗力,而這種事對(duì)計(jì)算機(jī)來說可是小菜一碟。

接下來,我們來寫一個(gè)簡單的密碼破解器。為了方便窮舉、快速破解密碼,我們規(guī)定密碼只有 4 位純數(shù)字。因此,只需要窮舉 1000-9999 之間的所有數(shù)字和密碼對(duì)比即可。

拓展:現(xiàn)實(shí)中的密碼更加復(fù)雜,破解起來也更耗時(shí)。而且軟件會(huì)限制你嘗試的次數(shù),所以暴力破解是密碼破解的下下策。

from random import randint

a = 9876

while True:

? number = randint(1000, 9999)? #和第一句要一起使用,不能只用第二句

? if number == a:? # 最初等號(hào)只寫了一個(gè),后面的冒號(hào)也忘記了

? ? break

print(number)

我的這個(gè)程序使用的是隨機(jī)生成一個(gè)四位數(shù),然后比對(duì),從而破解。

password = 2349

i = 1000

while i != password:

? i = i + 1

? if i == password:

? ? break? ? ? ? ? # 這兩個(gè)可以去掉,因?yàn)閕不等于密碼的時(shí)候,才循環(huán),否則就退出循環(huán),打印i,所以這里不需要跳出循環(huán)的語句。

print(i)

password = 2349

i = 1000? ? ? #這個(gè)初始值也不需要,因?yàn)閞ange()會(huì)遍歷范圍內(nèi)的每個(gè)值,這個(gè)就不需要

for i in range(1000, 9999):

? i = i + 1? #這個(gè)也可以不要,因?yàn)槭潜闅v每個(gè)數(shù)字,然后比對(duì)的,所以不需要慢慢增加

? if i == password:

? ? break

print(i)


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容