1. 程式人生 > >Python基礎知識梳理 - 第03部分

Python基礎知識梳理 - 第03部分

if while for

程序語言中的流程控制語句用於控制計算操作執行的次序. 次序分為: 順序, 分支, 循環. 順序, 就是字面含義, 從上至下的運行; 分支, 根據各種條件, 進入相應的程序塊; 循環, 即多次進入相同的程序塊.



Python語言中分支的實現, 借助於if語句, 其一般形式如下:

if <test1>:

<statements1>

elif <test2>:

<statements2>

else:

<statements3>


當if語句執行時, Python會執行測試第一個計算結果為真的代碼塊, 或者如果所有測試都為假時, 就執行else塊.


if語句舉例如下:

In [1]: x = 'killer rabbit'


In [2]: if x == 'roger':

...: print("how's jessica?")

...: elif x == 'bugs':

...: print("what's up doc?")

...: else:

...: print('Run away! Run away!')

...:

Run away! Run away!


另外, 對於下面形式的代碼:

if X:

A = Y

else:

A = Z


還有個等價的形式, A = Y if X else Z, 即if/else三元表達式.



Python語言中循環的實現, 借助於while和for語句.


while語句一般形式如下:

while <test>:

<statements1>

else: # Optional else

<statements2> # Run if didn't exit loop with break


Python會一直計算開頭的測試, 然後執行循環主體內的語句, 直到測試返回假值為止, 之後執行可選的else部分. 若在循環主體內遇到break語句而退出, 即使有else部分, 也不會執行.


while語句舉例如下:

In [3]: x = 'spam'


In [4]: while x:

...: print(x, end=' ')

...: x = x[1:]

...:

spam pam am m


上面說到了break語句, 還有一個與之對應的continue語句, 它們都可以出現在while(還有後面要說到的for)循環主體的任何地方. break跳出最近所在的循環, continue則跳到最近所在循環的開頭. 更一般的格式如下:

while <test1>:

<statements1>

if <test2>: break # Exit loop now, skip else

if <test3>: continue # Go to top of loop now, to test1

else:

<statements2> # Run if didn't hit a 'break'



下面看看for循環, 其在Python中是一個通用的序列叠代器, 可以遍歷任何有序的序列對象內的元素.


一般格式如下:

for <target> in <object>: # Assign object items to target

<statements> # Repeated loop body: use target

else:

<statements2> # if didn't hit a 'break'


Python運行for循環時, 會逐個將序列對象中的元素賦值給目標, 然後為每個元素執行循環主體.


for語句舉例如下:

In [5]: for x in ['spam', 'eggs', 'ham']:

...: print(x, end=' ')

...:

spam eggs ham



編寫循環的技巧, 並行遍歷zip, ;產生偏移和元素enumerate.


zip舉例:

In [7]: L1 = [1, 2, 3, 4]


In [8]: L2 = [5, 6, 7, 8]


In [9]: for (x, y) in zip(L1, L2):

...: print(x, y, '---', x + y)

...:

1 5 --- 6

2 6 --- 8

3 7 --- 10

4 8 --- 12


enumerate舉例:

In [11]: for (offset, item) in enumerate(S, 1):

...: print(item, 'appears at offset', offset)

...:

s appears at offset 1

p appears at offset 2

a appears at offset 3

m appears at offset 4



剛才介紹for循環時, 說到其是一個通用的序列叠代器, 可以遍歷任何有序的序列對象內的元素, 如列表, 元組以及字符串. 實際, for循環可用於任何可叠代的對象.


可叠代對象是什麽呢, 如果對象是實際保存的序列, 或可以在叠代工具環境中一次產生一個結果的對象, 就看做是可叠代的.


那叠代器又是什麽呢, 先從文件叠代器來說, 已打開的文件對象有一個方法名為readline, 可以一次從一個文件中讀取一行文本, 每次調用readline方法時, 就會前進到下一行. 到達文件末尾時, 就會返回空字符串, 可通過它來檢測, 從而跳出循環.

In [48]: f = open('test.py')


In [49]: f.readline()

Out[49]: 'import sys\n'


In [50]: f.readline()

Out[50]: '\n'


In [51]: f.readline()

Out[51]: 'print(sys.path)\n'


In [52]: f.readline()

Out[52]: ''


文件對象還有一個方法, 名為__next__, 差不多有相同的效果, 每次調用時, 就會返回文件中的下一行. 唯一的區別在於, 到達文件末尾時, __next__會引發內置的StopIteration異常, 而不是返回空字符串.

In [53]: f = open('test.py')


In [54]: f.__next__()

Out[54]: 'import sys\n'


In [55]: f.__next__()

Out[55]: '\n'


In [56]: f.__next__()

Out[56]: 'print(sys.path)\n'


In [57]: f.__next__()

---------------------------------------------------------

StopIteration Traceback (most recent call last)

<ipython-input-57-dcf180275632> in <module>()

----> 1 f.__next__()


StopIteration:


這個接口描述的就是Python中的叠代協議: 實現了__next__方法的對象, 會前進到下一個結果, 而到達一系列結果的末尾時, 則會引發StopIteration異常. 至此, 可以說明, 文件叠代器, 實現了叠代協議.


看下更為通用的for循環, 當for循環開始時, 會通過它將可叠代對象傳遞給iter內置函數, 以便從可叠代對象獲得一個叠代器, 返回的對象就是叠代器了, 其實現了叠代協議.

In [60]: L = [1, 2, 3]


In [61]: I = iter(L)


In [62]: I.__next__()

Out[62]: 1


In [63]: I.__next__()

Out[63]: 2


In [64]: I.__next__()

Out[64]: 3


In [65]: I.__next__()

---------------------------------------------------------

StopIteration Traceback (most recent call last)

<ipython-input-65-a7fa90893753> in <module>()

----> 1 I.__next__()


StopIteration:


最初的一步對於文件來說不是必需的, 文件有自己的__next__方法, 不需要再像那樣返回一個對象了, 文件對象就是自己的叠代器.

In [73]: f = open('test.py')


In [74]: iter(f) is f

Out[74]: True


In [75]: f.__next__()

Out[75]: 'import sys\n'


對於列表, 以及很多其它的內置對象, 不是自身的叠代器, 必須調用iter來啟動叠代.

In [76]: L = [1, 2, 3]


In [77]: iter(L) is L

Out[77]: False


In [78]: L.__next__()

---------------------------------------------------------

AttributeError Traceback (most recent call last)

<ipython-input-78-98b0c0707a44> in <module>()

----> 1 L.__next__()


AttributeError: 'list' object has no attribute '__next__'


In [79]: I = iter(L)


In [80]: I.__next__()

Out[80]: 1


盡管Python中的叠代工具會自動調用這些函數, 也可以使用它們來手動應用叠代協議. 下面的例子展示了自動和手動叠代, 結果是等效的.

In [81]: L = [1, 2, 3]


In [82]: for X in L:

...: print(X ** 2, end=' ')

...:

1 4 9


In [83]: I = iter(L)


In [84]: while True:

...: try:

...: X = I.__next__()

...: except StopIteration:

...: break

...: print(X ** 2, end=' ')

...:

1 4 9


若感興趣可關註訂閱號”數據庫最佳實踐”(DBBestPractice).

技術分享圖片

Python基礎知識梳理 - 第03部分