本文為《爬著學(xué)Python》系列第七篇文章幢哨。
我們拖了好久,終于要開(kāi)始真正進(jìn)行Python語(yǔ)法的講解了嫂便。是的捞镰,變量與對(duì)象只是Python的語(yǔ)義特征,編程語(yǔ)言的語(yǔ)法特征體現(xiàn)在控制結(jié)構(gòu)顽悼。
也就是我們一般說(shuō)的if曼振,while。
我們今天要講的主要就是這兩種控制結(jié)構(gòu)蔚龙,即判斷和循環(huán)結(jié)構(gòu)冰评。而且,我們涉及的是非常簡(jiǎn)單而樸素的控制結(jié)構(gòu)木羹。關(guān)于迭代器甲雅、生成器、高級(jí)函數(shù)等知識(shí)會(huì)在Python進(jìn)階部分進(jìn)行討論坑填。我們先打好基礎(chǔ)抛人,后面學(xué)起來(lái)會(huì)比較輕松。
判斷
判斷結(jié)構(gòu)一般也叫條件判斷結(jié)構(gòu)脐瑰,簡(jiǎn)單理解起來(lái)妖枚,如果滿足什么條件,那么進(jìn)行什么樣的操作苍在。實(shí)現(xiàn)方式一般是if語(yǔ)句绝页。
我們直接在if后面接上判斷條件即可完成判斷,換行后空四個(gè)空格進(jìn)行根據(jù)判斷結(jié)果的執(zhí)行部分寂恬。
if 條件:
執(zhí)行語(yǔ)句
條件判斷結(jié)構(gòu)以外的執(zhí)行語(yǔ)句
注意到我們不需要任何形式的括號(hào)來(lái)包住執(zhí)行部分续誉,Python通過(guò)縮進(jìn)判斷語(yǔ)句的結(jié)構(gòu)。當(dāng)你的縮進(jìn)與if語(yǔ)句對(duì)齊時(shí)初肉,自動(dòng)退出條件判斷結(jié)構(gòu)酷鸦。在命令行中,我們通過(guò)空行來(lái)實(shí)現(xiàn)退出:
>>> a = 3
>>> if a > 2:
... print('a is bigger than 2')
...
a is bigger than 2
簡(jiǎn)單的判斷語(yǔ)句結(jié)構(gòu)就是這樣。當(dāng)if后面的條件滿足時(shí)臼隔,就會(huì)執(zhí)行判斷結(jié)構(gòu)中的執(zhí)行語(yǔ)句嘹裂,否則直接跳過(guò)執(zhí)行部分推出判斷結(jié)構(gòu)。
布爾值
為了進(jìn)一步了解條件判斷結(jié)構(gòu)躬翁,我們需要了解一下布爾值這種數(shù)據(jù)類型焦蘑。
>>> type(True)
<class 'bool'>
布爾值分為兩種,True
和False
盒发,即我們一般所說(shuō)的“真”和“假”例嘱。在Python中布爾值一般有兩種出現(xiàn)方式,一種是直接賦值給變量宁舰,一種是通過(guò)判斷來(lái)得到拼卵。
>>> a = True
>>> if a:
... print('a')
...
a
>>> if a is True:
... print('a is True')
...
a is True
其中,a = True
是直接把布爾值True
賦給變量a
蛮艰,所以我們把a
當(dāng)作判斷條件的時(shí)候腋腮,程序會(huì)完成執(zhí)行部分。而a is True
則是在進(jìn)行判斷壤蚜,這個(gè)判斷的結(jié)果為True
即寡,所以程序一樣會(huì)完成執(zhí)行部分。
而我們所謂的“進(jìn)行判斷”袜刷,其實(shí)可以看作條件判斷結(jié)構(gòu)中會(huì)自動(dòng)對(duì)判斷條件調(diào)用bool()
函數(shù)聪富。
>>> bool(a > 3)
False
事實(shí)上,之前提到的條件判斷結(jié)構(gòu)中if 條件:
是根據(jù)條件返回的的布爾值來(lái)進(jìn)行判斷完成功能的著蟹。條件返回值為True
則執(zhí)行墩蔓,否則不執(zhí)行。這也是為什么if a:
可以當(dāng)作判斷條件萧豆。
布爾值其他細(xì)節(jié)
我們知道了if 條件:
在進(jìn)行判斷時(shí)奸披,實(shí)際上是在判斷條件
表達(dá)式返回的布爾值。因此返回布爾值的任何對(duì)象都可以作為判斷條件涮雷。
常見(jiàn)的是值的大小比較阵面,即>
,<
洪鸭,>=
膜钓,<=
。很好理解卿嘲,它們分別對(duì)應(yīng)“大于”、“小于”夫壁、“大于等于”拾枣、“小于等于”。
我們要特別把等于單獨(dú)說(shuō)是因?yàn)椋覀儾荒苤苯佑玫忍?hào)來(lái)判斷是否等于梅肤,例如if a = 3:
司蔬,我們很清楚a = 3
是個(gè)賦值語(yǔ)句,這樣會(huì)造成歧義姨蝴。因此俊啼,在判斷相等時(shí),我們連用兩個(gè)等號(hào)if a == 3:
左医,不等于的形式為if a != 3:
授帕。
之后我們需要知道的,就是布爾值的簡(jiǎn)單邏輯運(yùn)算浮梢,包括“與”跛十、“或”、“非”秕硝,Python中分別表示為 and
芥映,or
,not
远豺。
-
條件A 與 條件B
在兩個(gè)條件都為真時(shí)整個(gè)表達(dá)式的布爾值為真奈偏,否則為假。 -
條件A 或 條件B
在兩個(gè)條件都為假時(shí)整個(gè)表達(dá)式的布爾值為假躯护,否則為真惊来。 -
非 條件
直接反轉(zhuǎn)條件的布爾值。
我們可以看出and
和or
是二元操作符榛做,not
是一元操作符唁盏。
布爾值的邏輯結(jié)構(gòu)可以組合使用,其中and
和or
結(jié)合優(yōu)先度高于not
检眯,但為了代碼可讀性厘擂,還是建議在組合邏輯結(jié)構(gòu)中使用括號(hào)方便理解。
>>> a = 3
>>> if not (a > 2 and a < 4):
... print(a)
...
>>>
最后要補(bǔ)充一點(diǎn)的就是锰瘸,除了布爾值以外刽严,其實(shí)還有一些情況也能作為判斷條件。
>>> if a:
... print('a')
...
但我們直接把變量當(dāng)作判斷條件時(shí)避凝,它也可以不必是布爾值舞萄,對(duì)象直接作為判斷條件會(huì)返回一個(gè)布爾值。對(duì)于整型和浮點(diǎn)數(shù)來(lái)說(shuō)管削,0
為假倒脓;對(duì)于簡(jiǎn)單數(shù)據(jù)結(jié)構(gòu),包括字符串含思,它的內(nèi)容為空時(shí)是假崎弃;最后None
是假甘晤。
None
就好像布爾值變量一樣是一種特殊的數(shù)據(jù)類型。它的類型叫作無(wú)類型饲做。
>>> type(None)
<class 'NoneType'>
再舉幾個(gè)例子驗(yàn)證一下:
>>> bool(0.0)
False
>>> bool([])
False
>>> bool(None)
False
>>> bool([None])
True
>>> bool('None')
True
最后還要提醒一點(diǎn)线婚,不要輕易用浮點(diǎn)數(shù)當(dāng)作判斷條件。因?yàn)镻ython中是把一個(gè)極小的浮點(diǎn)數(shù)作為0來(lái)使用的盆均。
>>> bool(1e-323)
True
>>> bool(1e-324)
False
判斷結(jié)構(gòu)中的else
我們剛才說(shuō)的判斷結(jié)構(gòu)的邏輯是塞弊,如果滿足條件就做一些對(duì)應(yīng)的事情,否則不做泪姨。其實(shí)游沿,判斷結(jié)構(gòu)還可以完成:如果滿足條件就做一些對(duì)應(yīng)的事情,否則做另一些事情驴娃。使用else
就能完成這樣的功能:
>>> a = 3
>>> if a > 4:
... print('a is bigger than 4')
... else:
... print('a is not bigger than 4')
...
a is not bigger than 4
這種結(jié)構(gòu)比較簡(jiǎn)單奏候,易于理解。
事實(shí)上唇敞,else 還可以再次進(jìn)行判斷蔗草,但我們要用elif
來(lái)完成更具體的條件判斷結(jié)構(gòu):
>>> a = 4
>>> if a > 4:
... print('a is bigger than 4')
... elif a < 4:
... print('a is smaller than 4')
... else:
... print('a is equal to 4')
...
a is equal to 4
如果使用這種結(jié)構(gòu)根據(jù)不同情況分別處理時(shí),不管有沒(méi)有窮盡所有可能疆柔,都建議最后留出一個(gè)else:
來(lái)處理一些其他情況防止遺漏咒精。
關(guān)于條件判斷結(jié)構(gòu),最后要說(shuō)的是旷档,Python并不具有switch結(jié)構(gòu)模叙,可以用字典檢索通過(guò)表驅(qū)動(dòng)的方式來(lái)完成這樣的功能。
def function_1(...):
...
functions = {'a': function_1,
'b': function_2,
'c': self.method_1, ...}
func = functions[value]
func()
詳見(jiàn)Design and History FAQ — Python 2.7.13 documentation鞋屈。
循環(huán)
講過(guò)判斷結(jié)構(gòu)以后再來(lái)講循環(huán)就簡(jiǎn)單了范咨。我們知道條件判斷結(jié)構(gòu)是用來(lái)讓程序根據(jù)某種條件做或者不做某種事情。當(dāng)我們需要程序重復(fù)做某件事情的時(shí)候厂庇,我們就需要循環(huán)結(jié)構(gòu)了渠啊。
Python循環(huán)結(jié)構(gòu)主要有兩種實(shí)現(xiàn)語(yǔ)法,一種是按條件循環(huán)权旷,一種是按次數(shù)循環(huán)替蛉,對(duì)應(yīng)的方法分別是while
和for
。
while
簡(jiǎn)單使用的具體結(jié)構(gòu)如下:
while 條件:
執(zhí)行語(yǔ)句
循環(huán)結(jié)構(gòu)以外的語(yǔ)句
不難看出拄氯,while
的用法和if
大同小異躲查。區(qū)別在于,if
只判斷一次條件译柏,程序順序執(zhí)行镣煮;while
重復(fù)判斷,只要條件滿足鄙麦,程序重復(fù)執(zhí)行怎静,直到條件第一次不滿足為止邮弹。
>>> a = 3
>>> while a > 0 :
... print(a)
... a -= 1
...
3
2
1
上面這個(gè)控制結(jié)構(gòu)實(shí)現(xiàn)的功能很簡(jiǎn)單,依次輸出小于等于a的所有正整數(shù)蚓聘。我們實(shí)現(xiàn)的方法是輸出a之后把a(bǔ)減去1,直到a不大于0了停止盟劫。
在while
循環(huán)結(jié)構(gòu)中夜牡,我們的條件
部分工作原理和判斷結(jié)構(gòu)中相似。但在循環(huán)結(jié)構(gòu)中侣签,有一個(gè)新的問(wèn)題塘装,一般來(lái)說(shuō),循環(huán)結(jié)構(gòu)需要一個(gè)“出口”來(lái)停止循環(huán)影所。這個(gè)出口有兩種實(shí)現(xiàn)方式蹦肴,一種是通過(guò)破壞判斷條件來(lái)退出,一種是在循環(huán)結(jié)構(gòu)內(nèi)部設(shè)計(jì)判斷結(jié)構(gòu)來(lái)退出猴娩。我們先講前者阴幌,后者在介紹完for
循環(huán)結(jié)構(gòu)以后再討論。
正如剛才的示例循環(huán)結(jié)構(gòu)一樣卷中,當(dāng)循環(huán)條件可變時(shí)矛双,程序就有可能退出。而我們?cè)O(shè)計(jì)循環(huán)結(jié)構(gòu)時(shí)蟆豫,會(huì)有意地設(shè)置循環(huán)條件议忽,讓程序在適當(dāng)?shù)臅r(shí)候退出循環(huán)結(jié)構(gòu)。我們可以在執(zhí)行語(yǔ)句的基礎(chǔ)上增加一個(gè)變量作為循環(huán)次數(shù)的“計(jì)數(shù)器”:
>>> i = 0
>>> while i < 3 :
... print('hello')
... i += 1
...
hello
hello
hello
在這個(gè)程序中十减,變量i
沒(méi)有實(shí)際意義栈幸,它是用來(lái)保存循環(huán)次數(shù)的變量“锉伲可以看得出來(lái)速址,我們?cè)谑褂?code>i之前要對(duì)其賦值進(jìn)行初始化,再進(jìn)行使用织阅,這很不方便壳繁。事實(shí)上,while
語(yǔ)句更多的是用來(lái)進(jìn)行循環(huán)次數(shù)不可知或者量極大時(shí)才會(huì)使用的荔棉,有事我們會(huì)看到while True:
這樣的語(yǔ)句闹炉,這是無(wú)限循環(huán),會(huì)永遠(yuǎn)進(jìn)行下去润樱。對(duì)于循環(huán)次數(shù)比較確定的場(chǎng)景渣触,for
循環(huán)結(jié)構(gòu)更加得心應(yīng)手。
for
循環(huán)的一般結(jié)構(gòu)如下:
for 變量 in 范圍:
執(zhí)行語(yǔ)句
循環(huán)結(jié)構(gòu)以外的語(yǔ)句
其中變量是用來(lái)標(biāo)記范圍中的元素壹若,方便在執(zhí)行語(yǔ)句中對(duì)其進(jìn)行操作或者引用嗅钻;范圍是個(gè)可迭代對(duì)象(iterable)皂冰,一般來(lái)說(shuō)是簡(jiǎn)單數(shù)據(jù)結(jié)構(gòu)如列表字典等,也可以是迭代器养篓,最簡(jiǎn)單的是range
類型的對(duì)象秃流。我們剛才說(shuō)到if
和while
在判斷條件時(shí)會(huì)自動(dòng)調(diào)用bool()
函數(shù),其實(shí)for
語(yǔ)句一直在調(diào)用next()
函數(shù)柳弄,相關(guān)內(nèi)容以后深入舶胀,目前了解即可。
range
是外形最為原始的Python內(nèi)置類碧注。定義方式就像普通類嚣伐,range
接受3個(gè)參數(shù)range(a, b, c)
,你可以把它看作會(huì)生成一個(gè)以a
為首項(xiàng)萍丐,c
為公差轩端,元素小于b
的列表。當(dāng)只給兩個(gè)參數(shù)時(shí)逝变,默認(rèn)c=1
基茵,當(dāng)只給一個(gè)參數(shù)時(shí),默認(rèn)a=0, c=1
骨田。
我們之前while
中的例子可以改寫為:
>>> for i in range(3):
... print(i + 1)
...
1
2
3
關(guān)于for
方法的一些技巧性的操作耿导,會(huì)在以后的簡(jiǎn)單數(shù)據(jù)結(jié)構(gòu)和函數(shù)式編程相關(guān)內(nèi)容中進(jìn)一步介紹。
break和continue
我們之前提到态贤,退出循環(huán)有兩種方式舱呻,一種是通過(guò)破壞循環(huán)條件退出,另一種悠汽,就是在循環(huán)結(jié)構(gòu)內(nèi)部退出箱吕。
首先,return
會(huì)跳出當(dāng)前函數(shù)運(yùn)行環(huán)境柿冲,因此在循環(huán)體內(nèi)可以作為退出的方式茬高。我們可以在函數(shù)體內(nèi)部增加一個(gè)判斷結(jié)構(gòu),在某個(gè)變量滿足某個(gè)條件時(shí)假抄,函數(shù)取得返回值怎栽,程序退出循環(huán)結(jié)構(gòu)所在的函數(shù)。
不過(guò)return
不是我們要講的重點(diǎn)宿饱,有關(guān)內(nèi)容會(huì)在程序結(jié)構(gòu)設(shè)計(jì)等內(nèi)容中討論熏瞄。我們要說(shuō)的是break
和continue
,我們作為比較將兩者一起講谬以。
>>> for i in range(3):
... print('running')
... if i > 0:
... break
... print(i)
...
running
0
running
break
會(huì)直接退出循環(huán)結(jié)構(gòu)强饮。
>>> for i in range(3):
... print('running')
... if i > 0:
... continue
... print(i)
...
running
0
running
running
continue
會(huì)跳過(guò)循環(huán)結(jié)構(gòu)中本次執(zhí)行過(guò)程中continue
后面的執(zhí)行語(yǔ)句,但是不會(huì)破環(huán)循環(huán)使其結(jié)束为黎,循環(huán)會(huì)從循環(huán)變量的下一個(gè)值繼續(xù)運(yùn)行邮丰,繼續(xù)判斷行您,繼續(xù)執(zhí)行,直到循環(huán)結(jié)構(gòu)有其他出口退出循環(huán)剪廉。
循環(huán)結(jié)構(gòu)中的else
我們剛才判斷結(jié)構(gòu)最后說(shuō)了一個(gè)else
的功能娃循,即規(guī)定在判斷條件不滿足時(shí)才執(zhí)行的語(yǔ)句。其實(shí)循環(huán)結(jié)構(gòu)中也可以使用else
關(guān)鍵字斗蒋,但是應(yīng)用場(chǎng)景不是很多淮野。
>>> for i in range(3):
... print('running')
... if i > 0:
... continue
... print(i)
... else:
... print('ending')
...
running
0
running
running
ending
可以看到上面的這段腳本輸出結(jié)果是不一樣的。在這里吹泡,只是為了展示一下while
語(yǔ)句中else
的格式,要注意不能把else
和if
對(duì)齊经瓷,否則就成了判斷語(yǔ)句的一部分了爆哑。
else
在循環(huán)結(jié)構(gòu)中的功能為,如果循環(huán)條件沒(méi)有被破環(huán)即循環(huán)次數(shù)用完后正常退出循環(huán)結(jié)構(gòu)舆吮,則執(zhí)行else
部分的語(yǔ)句揭朝,否則跳過(guò)。所以else
往往是和continue
和break
搭配使用色冀,這也是為什么要先講循環(huán)的退出再討論循環(huán)中else
的運(yùn)用潭袱。循環(huán)中的else
在各種項(xiàng)目中見(jiàn)得不多,主要是因?yàn)闀?huì)影響代碼的可讀性锋恬。只要能理解別人代碼中出現(xiàn)的這種結(jié)構(gòu)就可以了屯换,對(duì)控制結(jié)構(gòu)操作技巧要求較高的可以嘗試使用。
熟練運(yùn)用控制結(jié)構(gòu)的功能是必備的能力与学,這需要積極練習(xí)加深理解彤悔。實(shí)際運(yùn)用中,尤其是面向過(guò)程時(shí)索守,我們會(huì)將判斷和循環(huán)結(jié)構(gòu)交相嵌套晕窑,完成相應(yīng)的復(fù)雜功能。這些都會(huì)在以后的深入學(xué)習(xí)中逐漸接觸卵佛。
至此杨赤,我計(jì)劃中的Python基礎(chǔ)部分就算告一段落了。我們第一次接觸了Python對(duì)象的概念截汪,我們見(jiàn)識(shí)了Python簡(jiǎn)單數(shù)據(jù)類型的使用方式疾牲,我們初步了解了Python中控制結(jié)構(gòu)的形式。這就算有一些Python基礎(chǔ)了挫鸽。
接下來(lái)我們會(huì)開(kāi)始嘗試Python的實(shí)際使用说敏,我們需要了解Python的內(nèi)置數(shù)據(jù)結(jié)構(gòu)的基本用法,我們需要學(xué)會(huì)定義函數(shù)集成一些簡(jiǎn)單的功能丢郊,我們需要了解Python第三方庫(kù)的使用方法和管理工具盔沫,之后医咨,我們就可以開(kāi)始嘗試編寫第一個(gè)爬蟲(chóng)了。