Python學習之高階特性

stonezhu發表於2018-06-16

Python學習目錄

  1. 在Mac下使用Python3
  2. Python學習之資料型別
  3. Python學習之函式
  4. Python學習之高階特性
  5. Python學習之函數語言程式設計
  6. Python學習之模組
  7. Python學習之物件導向程式設計
  8. Python學習之物件導向高階程式設計
  9. Python學習之錯誤除錯和測試
  10. Python學習之IO程式設計
  11. Python學習之程式和執行緒
  12. Python學習之正則
  13. Python學習之常用模組
  14. Python學習之網路程式設計

練習程式碼

掌握了Python的資料型別、語句和函式,基本上就可以編寫出很多有用的程式了。比如構造一個1, 3, 5, 7, ..., 99的列表,可以通過迴圈實現:

L = []
n = 1
while n <= 99:
    L.append(n)
    n = n + 2
複製程式碼

取list的前一半的元素,也可以通過迴圈實現。

但是在Python中,程式碼不是越多越好,而是越少越好。程式碼不是越複雜越好,而是越簡單越好。基於這一思想,我們來介紹Python中非常有用的高階特性,1行程式碼能實現的功能,決不寫5行程式碼。請始終牢記,程式碼越少,開發效率越高。

切片(Slice)

L = list(range(100))
L[:10]

>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

(0, 1, 2, 3, 4, 5)[:3]

>>> (0, 1, 2)

'ABCDEFG'[:3]

>>> 'ABC'
複製程式碼

在很多程式語言中,針對字串提供了很多各種擷取函式(例如,substring),其實目的就是對字串切片。Python沒有針對字串的擷取函式,只需要切片一個操作就可以完成,非常簡單。

迭代

  1. 通過collections模組的Iterable型別判斷物件是否為可迭代物件
from collections import Iterable
isinstance('abc', Iterable) # str是否可迭代

>>> True
複製程式碼
  1. Python內建的enumerate函式可以把一個list變成索引-元素對,這樣就可以在for迴圈中同時迭代索引和元素本身
for i, value in enumerate(['A', 'B', 'C']):
    print(i, value)

>>>
    0 A
    1 B
    2 C
複製程式碼

列表生成

  1. list(range(1, 11))
  2. 生成[1x1, 2x2, 3x3, ..., 10x10]
L = []
for x in range(1, 11):
    L.append(x * x)
複製程式碼
  1. 列表生成式(list comprehensions)可以用一行語句代替迴圈生成上面的list
[x * x for x in range(1, 11)]
複製程式碼

生成器(generator)

generator儲存的是演算法,每次呼叫next(g),就計算出g的下一個元素的值,直到計算到最後一個元素,沒有更多的元素時,丟擲StopIteration的錯誤; 同樣也可以使用for迴圈遍歷

  1. 把一個列表生成式的[]改成()
g = (x * x for x in range(10))
for n in g:
   print(n)

>>>
    0
    1
    4
    9
    16
    25
    36
    49
    64
    81
複製程式碼
  1. 函式定義中包含yield關鍵字,那麼這個函式就不再是一個普通函式,而是一個generator

generator和函式的執行流程不一樣。函式是順序執行,遇到return語句或者最後一行函式語句就返回。而變成generator的函式,在每次呼叫next()的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行。 把函式改成generator後,我們基本上從來不會用next()來獲取下一個返回值,而是直接使用for迴圈來迭代

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'
f = fib(6)
複製程式碼

迭代器

  1. 可以直接作用於for迴圈的資料型別有以下幾種: 一類是集合資料型別,如list、tuple、dict、set、str等; 一類是generator,包括生成器和帶yield的generator function

這些可以直接作用於for迴圈的物件統稱為可迭代物件:Iterable。可以使用isinstance()判斷一個物件是否是Iterable物件。 而生成器不但可以作用於for迴圈,還可以被next()函式不斷呼叫並返回下一個值,直到最後丟擲StopIteration錯誤表示無法繼續返回下一個值了。可以被next()函式呼叫並不斷返回下一個值的物件稱為迭代器:Iterator。可以使用isinstance()判斷一個物件是否是Iterator物件。

  1. 集合資料型別如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函式獲得一個Iterator物件。
  2. Python的for迴圈本質上就是通過不斷呼叫next()函式實現的。
for x in [1, 2, 3, 4, 5]:
    pass
複製程式碼

完全等同於:

# 首先獲得Iterator物件:
it = iter([1, 2, 3, 4, 5])
# 迴圈:
while True:
    try:
        # 獲得下一個值:
        x = next(it)
    except StopIteration:
        # 遇到StopIteration就退出迴圈
        break
複製程式碼

小結:Python的Iterator物件表示的是一個資料流,這個資料流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函式實現按需計算下一個資料,所以Iterator的計算是惰性的,只有在需要返回下一個資料時它才會計算。 Iterator甚至可以表示一個無限大的資料流,例如全體自然數。而使用list是永遠不可能儲存全體自然數的。

下一篇:Python學習之函數語言程式設計

相關文章