Python入門(mén)第4/10頁(yè)
更新時(shí)間:2007年02月08日 00:00:00 作者:
第四章 流程控制
前面我們已經(jīng)見(jiàn)到了如何由用while結(jié)構(gòu)控制流程運(yùn)行。這一章我們介紹更多的控制結(jié)構(gòu)。Python具有和其它語(yǔ)言類(lèi)似的控制結(jié)構(gòu)但略有差別。
4.1 If 語(yǔ)句
If 語(yǔ)句可能是最基本的程序分支語(yǔ)句了。例如:
>>> if x < 0:
... x = 0
... print 'Negative changed to zero'
... elif x == 0:
... print 'Zero'
... elif x == 1:
... print 'Single'
... else:
... print 'More'
...
可以有零到多個(gè)elif部分,else部分可選。關(guān)鍵字elif是else if的縮寫(xiě),這樣可以縮短語(yǔ)句行長(zhǎng)度。其它語(yǔ)言中switch 或 case 語(yǔ)句可以用if...elif...elif...語(yǔ)句組來(lái)實(shí)現(xiàn)。
4.2 for 語(yǔ)句
Python中的for語(yǔ)句與你可能熟悉的C或者Pascal中的相應(yīng)語(yǔ)句略有不同。不象Pascal 那樣總是對(duì)數(shù)字序列進(jìn)行循環(huán),也不是象C中那樣完全由程序員自由地控制循環(huán)條件和循環(huán)體,Python的for循環(huán)是對(duì)任意種類(lèi)的序列(如列表或字符串)按出現(xiàn)次序遍歷每一項(xiàng)。例如:
>>> # 計(jì)算字符串長(zhǎng):
... a = ['cat', 'window', 'defenestrate']
>>> for x in a:
... print x, len(x)
...
cat 3
window 6
defenestrate 12
>>>
盡量不要在循環(huán)體內(nèi)修改用來(lái)控制循環(huán)的序列(當(dāng)然,只有可變的序列類(lèi)型如列表才有可能被修改),這樣程序可能會(huì)出問(wèn)題。如果需要這樣,比如說(shuō)要復(fù)制某些項(xiàng),可以用序列的副本來(lái)控制循環(huán)。片段記號(hào)讓你很容易生成副本:
>>> for x in a[:]: # 生成整個(gè)列表的片段副本
... if len(x) > 6: a.insert(0, x)
...
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']
>>>
結(jié)果是把列表中長(zhǎng)度超過(guò)6個(gè)字符的字符串插入到列表開(kāi)頭。
4.3 range() 函數(shù)
如果確實(shí)需要對(duì)一列數(shù)字進(jìn)行循環(huán)的話,可以使用內(nèi)置函數(shù)range()。它生成包含數(shù)字序列的列表,如:
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
注意給出的終點(diǎn)永遠(yuǎn)不出現(xiàn)在生成的列表中,range(10)生成一個(gè)十個(gè)數(shù)的列表,恰好是長(zhǎng)度為10的序列的合法下標(biāo)的各個(gè)值。也可以指定不同的起始點(diǎn),或者指定不同的間隔(甚至負(fù)數(shù)):
>>> range(5, 10)
[5, 6, 7, 8, 9]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(-10, -100, -30)
[-10, -40, -70]
>>>
為了對(duì)序列的下標(biāo)進(jìn)行循環(huán),如下聯(lián)合使用range() 和 len():
>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
... print i, a[i]
...
0 Mary
1 had
2 a
3 little
4 lamb
>>>
4.4 break語(yǔ)句,continue語(yǔ)句和循環(huán)中的else子句
如同C語(yǔ)言一樣,break語(yǔ)句跳出其所處的最內(nèi)層的for 或 while循環(huán),continue語(yǔ)句繼續(xù)下一循環(huán)步。
循環(huán)語(yǔ)句還可以帶一個(gè) else 子句,當(dāng)循環(huán)正常結(jié)束時(shí)執(zhí)行其內(nèi)容,但如果循環(huán)是用break 語(yǔ)句跳出的則不執(zhí)行其內(nèi)容。下例說(shuō)明了這種用法,此例求素?cái)?shù):
>>> for n in range(2, 10):
... for x in range(2, n):
... if n % x == 0:
... print n, 'equals', x, '*', n/x
... break
... else:
... print n, 'is a prime number'
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
>>>
4.5 pass 語(yǔ)句
pass語(yǔ)句不執(zhí)行任何操作,當(dāng)語(yǔ)法要求一個(gè)語(yǔ)句而程序不需要執(zhí)行操作時(shí)就用此語(yǔ)句。例如:
>>> while 1:
... pass # 等待鍵盤(pán)中斷
...
4.6 函數(shù)定義
我們可以定義一個(gè)函數(shù)用來(lái)計(jì)算某一界限以下的所有Fibonacci序列值:
>>> def fib(n): # 寫(xiě)出 n 以下的所有Fibonacci序列值
... a, b = 0, 1
... while b < n:
... print b,
... a, b = b, a+b
...
>>> # 調(diào)用剛剛定義的函數(shù):
... fib(2000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
>>>
其中關(guān)鍵字 def 開(kāi)始一個(gè)函數(shù)定義,其后應(yīng)該是函數(shù)名,括號(hào)內(nèi)的形參表,以冒號(hào)結(jié)束。構(gòu)成函數(shù)體的各語(yǔ)句從下一行開(kāi)始,用一個(gè)制表符縮進(jìn)。函數(shù)的第一個(gè)語(yǔ)句可以是一個(gè)字符串,如果是的話,這個(gè)字符串就是函數(shù)的文檔字符串,簡(jiǎn)稱(chēng)為docstring。有一些工具可以利用文檔字符串自動(dòng)生成可打印的文檔,或者讓用戶交互地瀏覽代碼,所以在自己編程時(shí)加入文檔字符串是一個(gè)好習(xí)慣,應(yīng)該養(yǎng)成這樣的習(xí)慣。
函數(shù)在執(zhí)行時(shí)對(duì)局部變量引入一個(gè)新的符號(hào)表。函數(shù)中的變量賦值都存入局部符號(hào)表;引用變量時(shí)變量名先從局部符號(hào)表中查找,然后在全局符號(hào)表中查找,最后從內(nèi)置的名字中查找。因此,在函數(shù)中不能直接對(duì)全局變量賦值(除非用了global語(yǔ)句來(lái)說(shuō)明),但可以引用全局變量的值。
函數(shù)調(diào)用的實(shí)參被引入函數(shù)的局部符號(hào)表,即函數(shù)的參數(shù)是按值調(diào)用的。函數(shù)再調(diào)用其它函數(shù)時(shí)為該函數(shù)生成一個(gè)新的符號(hào)表。但是嚴(yán)格地說(shuō),函數(shù)的調(diào)用是按引用調(diào)用的,因?yàn)槿绻麉?shù)是一個(gè)可變類(lèi)型如列表的話在函數(shù)中改變形參的內(nèi)容將導(dǎo)致實(shí)參的內(nèi)容被改變(不改變的是實(shí)參名字的綁定關(guān)系)。
函數(shù)定義把函數(shù)名放入當(dāng)前符號(hào)表。函數(shù)名的值類(lèi)型為用戶自定義函數(shù),這個(gè)值可以賦給另一個(gè)名字,從而這個(gè)名字也代表相同的函數(shù)。這可以作為一般的改名方法:
>>> fib
<function object at 10042ed0>
>>> f = fib
>>> f(100)
1 1 2 3 5 8 13 21 34 55 89
>>>
你可能會(huì)說(shuō) fib 不是函數(shù)而是過(guò)程。Python和C一樣,過(guò)程只是不返回值的函數(shù)。實(shí)際上,嚴(yán)格地說(shuō),過(guò)程也返回一個(gè)值,只不過(guò)是一個(gè)很沒(méi)意思的值。這個(gè)值叫做 None(這是一個(gè)內(nèi)置的名字)。解釋程序交互運(yùn)行時(shí)如果只需要顯示這個(gè)值的話就會(huì)忽略不顯示。如果希望顯示的話可以用 print 語(yǔ)句:
>>> print fib(0)
None
>>>
也可以寫(xiě)一個(gè)函數(shù)返回Fibonacci 序列的數(shù)值列表而不是顯示這些值:
>>> def fib2(n): # 返回直到n的Fibonacci 序列值
... result = []
... a, b = 0, 1
... while b < n:
... result.append(b) # 解釋見(jiàn)下面
... a, b = b, a+b
... return result
...
>>> f100 = fib2(100) # 調(diào)用
>>> f100 # 輸出結(jié)果
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>>
這個(gè)例子也演示了新的Python特色:return語(yǔ)句從函數(shù)中退出并返回一個(gè)值。不帶返回值的return可以從過(guò)程中間退出,運(yùn)行到過(guò)程的末尾也可以退出,這兩種情況下返回None。
語(yǔ)句result.append(b)調(diào)用列表對(duì)象result的一個(gè)方法。方法是“屬于”一個(gè)對(duì)象的函數(shù),引用格式為obj.methodname,其中obj是某個(gè)對(duì)象(也允許是一個(gè)表達(dá)式), methodname 是由該對(duì)象的類(lèi)型定義的一個(gè)方法的名字。不同的不同的方法。不同類(lèi)型的方法可以使用相同的名字而不致引起誤解。(可以定義自己的對(duì)象類(lèi)型和方法,使用類(lèi),本文后面會(huì)討論這個(gè)話題)。例子中的append()方法時(shí)列表對(duì)象的方法,它在列表末尾增加一個(gè)新元素。在本例中這等價(jià)于“result = result + [b]”,只是更有效。
4.7 函數(shù)參數(shù)
可以定義使用可變個(gè)數(shù)參數(shù)的函數(shù)。這樣的定義方法有三種,可以聯(lián)合使用。
4.7.1 參數(shù)缺省值
可以為一個(gè)參數(shù)或幾個(gè)參數(shù)指定缺省值。這樣定義的函數(shù)在調(diào)用時(shí)實(shí)參個(gè)數(shù)可以比定義時(shí)少。例如:
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
while 1:
ok = raw_input(prompt)
if ok in ('y', 'ye', 'yes'): return 1
if ok in ('n', 'no', 'nop', 'nope'): return 0
retries = retries - 1
if retries < 0: raise IOError, 'refusenik user'
print complaint
這個(gè)函數(shù)在調(diào)用時(shí)既可以這樣調(diào)用:ask_ok('Do you really want to quit?'),或者可以這樣調(diào)用:ask_ok('OK to overwrite the file?', 2)。缺省值是在函數(shù)定義時(shí)的定義作用域中計(jì)算的,所以例如:
i = 5
def f(arg = i): print arg
i = 6
f()
將顯示5。
注意:缺省值只計(jì)算一次。當(dāng)缺省值是可變對(duì)象如列表或字典時(shí)這一點(diǎn)是要注意的。例如,以下函數(shù)會(huì)在以后的調(diào)用中累加它的值:
def f(a, l = []):
l.append(a)
return l
print f(1)
print f(2)
print f(3)
This will print
[1]
[1, 2]
[1, 2, 3]
如果你不希望缺省值在連續(xù)的調(diào)用中被保留,可以象下面這樣改寫(xiě)函數(shù):
def f(a, l = None):
if l is None:
l = []
l.append(a)
return l
4.7.2 關(guān)鍵字參數(shù)
函數(shù)調(diào)用時(shí)也可以象“關(guān)鍵字 = 值”這樣指定實(shí)參,其中關(guān)鍵字是定義時(shí)使用的形參的名字。例如:
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print "-- This parrot wouldn't", action,
print "if you put", voltage, "Volts through it."
print "-- Lovely plumage, the", type
print "-- It's", state, "!"
可以用如下幾種方式調(diào)用:
parrot(1000) # 缺省值
parrot(action = 'VOOOOOM', voltage = 1000000) # 關(guān)鍵字,缺省值,次序可變
parrot('a thousand', state = 'pushing up the daisies') # 位置參數(shù),缺省值,關(guān)鍵字
parrot('a million', 'bereft of life', 'jump') # 位置參數(shù),缺省值
但以下幾種調(diào)用方式是錯(cuò)誤的:
parrot() # 非缺省的參數(shù)沒(méi)有提供
parrot(voltage=5.0, 'dead') # 關(guān)鍵字參數(shù)后面又出現(xiàn)了非關(guān)鍵字參數(shù)
parrot(110, voltage=220) # 參數(shù)值重復(fù)提供
parrot(actor='John Cleese') # 未知關(guān)鍵字
一般說(shuō)來(lái),實(shí)參表中位置參數(shù)在前,關(guān)鍵字參數(shù)在后,關(guān)鍵字名字必須是形參名字。形參有沒(méi)有缺省值都可以用關(guān)鍵字參數(shù)的形式調(diào)用。每一形參至多只能對(duì)應(yīng)一個(gè)實(shí)參,因此,已經(jīng)由位置參數(shù)傳入值的形參就不能在同一調(diào)用中再作為關(guān)鍵字參數(shù)。
如果形參表中有一個(gè)形為**name的形參,在調(diào)用時(shí)這個(gè)形參可以接收一個(gè)字典,字典中包含所有不與任何形參匹配的關(guān)鍵字參數(shù)。形參表中還可以使用一個(gè)特殊的如*name的形參,它將接受所有不能匹配的位置參數(shù)組成的一個(gè)序表。*name只能在**name之前出現(xiàn)。例如,如果定義了下面的函數(shù):
def cheeseshop(kind, *arguments, **keywords):
print "-- Do you have any", kind, '?'
print "-- I'm sorry, we're all out of", kind
for arg in arguments: print arg
print '-'*40
for kw in keywords.keys(): print kw, ':', keywords[kw]
就可以象下面這樣調(diào)用:
cheeseshop('Limburger', "It's very runny, sir.",
"It's really very, VERY runny, sir.",
client='John Cleese',
shopkeeper='Michael Palin',
sketch='Cheese Shop Sketch')
結(jié)果顯示:
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch
4.7.3 任意個(gè)數(shù)參數(shù)
在所有有名的形參的后面可以有兩個(gè)特殊的形參,一個(gè)以*args的形式命名,一個(gè)以**kw 的形式命名。有了*args形式的形參后函數(shù)在調(diào)用時(shí)就可以在正常的能匹配的實(shí)參表后面輸入任意個(gè)數(shù)的參數(shù),這些參數(shù)組成一個(gè)序表賦給args形參,不能匹配的關(guān)鍵字參數(shù)組成一個(gè)字典賦給kw形參。在任意個(gè)數(shù)形參之前可以有0到多個(gè)正常的參數(shù)。例如:
def fprintf(file, format, *args):
file.write(format % args)
4.7.4 Lambda形式
因?yàn)樵S多人的要求,Python中加入了一些在函數(shù)編程語(yǔ)言和Lisp中常見(jiàn)的功能。可以用lambda 關(guān)鍵字來(lái)定義小的無(wú)名函數(shù)。這是一個(gè)返回其兩個(gè)參數(shù)的和的函數(shù):“l(fā)ambda a, b: a+b” 。Lambda形式可以用于任何需要函數(shù)對(duì)象的地方。從句法上講lambda形式局限于一個(gè)表達(dá)式。從語(yǔ)義上講,這只是正常的函數(shù)定義的句法甜食。像嵌套函數(shù)定義一樣,lambda形式不能訪問(wèn)包含其定義的作用域中的變量,但審慎地使用缺省參數(shù)之可以繞過(guò)這個(gè)限制。例如:
def make_incrementor(n):
return lambda x, incr=n: x+incr
4.7.5 文檔字符串
關(guān)于文檔字符串的內(nèi)容與格式正在形成一些慣例。第一行應(yīng)該為簡(jiǎn)短的對(duì)象目的概括說(shuō)明。為了簡(jiǎn)明起見(jiàn),這一行不應(yīng)該提及對(duì)象的名字或類(lèi)型,因?yàn)檫@些可以通過(guò)其他途徑得知(當(dāng)然如果對(duì)象名字就是一個(gè)描述函數(shù)操作的動(dòng)詞則當(dāng)然可以提及其名字)。著以行應(yīng)該用大些字母開(kāi)始,以句點(diǎn)結(jié)尾。如果文檔字符串中有多行,第二行應(yīng)該是空行,把概括說(shuō)明與其它說(shuō)明分開(kāi)。以下的行可以是一段或幾段,描述對(duì)象的調(diào)用方法,它的副作用,等等。
Python的掃描程序不會(huì)從多行字符串中去掉縮進(jìn)空白,所以處理文檔的工具需要自己處理縮進(jìn)。只要遵循如下的慣例就可以有利于縮進(jìn)空白的處理。在第一行之后的第一個(gè)非空白的行決定整個(gè)文檔字符串的縮進(jìn)數(shù)量(我們不用第一行,因?yàn)樗?jīng)常是直接跟在表示字符串開(kāi)始的引號(hào)后面)。文檔字符串中除第一行以外的各行都要?jiǎng)h除等價(jià)于此行的縮進(jìn)量的空白。對(duì)制表符將擴(kuò)展為空格后再刪除。
您可能感興趣的文章:
- 為什么入門(mén)大數(shù)據(jù)選擇Python而不是Java?
- 小白如何入門(mén)Python? 制作一個(gè)網(wǎng)站為例
- python入門(mén)前的第一課 python怎樣入門(mén)
- Python入門(mén)之后再看點(diǎn)什么好?
- python入門(mén)教程 python入門(mén)神圖一張
- Python入門(mén)教程 超詳細(xì)1小時(shí)學(xué)會(huì)Python
- 一篇不錯(cuò)的Python入門(mén)教程
- Python3 入門(mén)教程 簡(jiǎn)單但比較不錯(cuò)
- wxPython 入門(mén)教程
- 人生苦短我用python python如何快速入門(mén)?
相關(guān)文章
Python 中下劃線的幾種用法(_、_xx、xx_、__xx、__xx__)
本文主要介紹了Python 中下劃線的幾種用法(_、_xx、xx_、__xx、__xx__),詳細(xì)的介紹了這幾種下劃線的用處,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09解決Python3中二叉樹(shù)前序遍歷的迭代問(wèn)題
二叉樹(shù)是分層數(shù)據(jù)結(jié)構(gòu),其中每個(gè)父節(jié)點(diǎn)最多有 2 個(gè)子節(jié)點(diǎn),在今天的文章中,我們將討論一個(gè)在大量技術(shù)編碼面試中出現(xiàn)的重要主題,對(duì)Python二叉樹(shù)遍歷相關(guān)知識(shí)感興趣的朋友一起看看吧2022-09-09Python 提取dict轉(zhuǎn)換為xml/json/table并輸出的實(shí)現(xiàn)代碼
這篇文章主要介紹了Python 提取dict轉(zhuǎn)換為xml/json/table并輸出的實(shí)現(xiàn)代碼,需要的朋友可以參考下2016-08-08python使用pypdf2實(shí)現(xiàn)pdf文檔解密
利用pypdf2完成pdf的解密,這里的事例是python3環(huán)境下的,當(dāng)然python2下也可以運(yùn)行,只需要修改名稱(chēng)即可,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12Python selenium+cookie實(shí)現(xiàn)免密登陸的示例代碼
本文主要介紹了Python selenium+cookie實(shí)現(xiàn)免密登陸的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02Tensorflow實(shí)現(xiàn)多GPU并行方式
今天小編就為大家分享一篇Tensorflow實(shí)現(xiàn)多GPU并行方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02