標籤: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方法時, 就會前進到下一行. 到達檔案末尾時, 就會返回Null 字元串, 可通過它來檢測, 從而跳出迴圈.
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異常, 而不是返回Null 字元串.
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部分