Python基礎知識梳理 - 第03部分
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部分