1. 程式人生 > >Python學習筆記三:高階特性

Python學習筆記三:高階特性

d = {'a' : 'A', 'b' : 'B', 'c' : 'C'}
L = [k + '=' + v for k, v in d.items()]
print(L) #輸出['a=A', 'b=B', 'c=C']

4.生成器(generator)

①一遍迴圈一遍計算的機制。通過不斷next(generator)獲得元素 ②建立一個generator的方法一:將列表生成式的 [] 號改成 () 號
L = [x * x for x in range(10)] #L是一個list
g = (x * x for x in range(10)) #g是一個generator
for n in g:
    print(n) #generator可迭代
③定義generator的另一種方法,如果一個函式定義中包含關鍵字yield,那麼這個函式不再是一個普通函式,而是一個generator:
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b #相當於t = (b, a + b)
                        #       a = t[0]
                        #       b = t[1]
                        #t是一個tuple
        n = n + 1
    return 'done'

for n in fib(5): #這裡的fib(5)就是一個generator物件
    print(n)
在變成generator的函式中,每次遇到yield都會返回,再次next()執行的時候,從上次的yield語句處繼續執行。如上面fib函式中,對fib(5)進行迭代遍歷是,每次遇到yield b就返回當前b的值,依次是1,1,2,3,5 ④用for...in迴圈呼叫generator時,拿不到generator的return語句的返回值。如果想要拿到返回值,必須捕獲StopIteration錯誤,返回值包含在StopIteration的value中:
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b #相當於t = (b, a + b)
                        #       a = t[0]
                        #       b = t[1]
                        #t是一個tuple
        n = n + 1
    return 'done'

g = fib(5) #構建generator物件
while True:
    try:
        x = next(g) #依次向後遍歷generator
        print(x)
    except StopIteration as e: #捕獲函式的返回值
        print('Generator return value', e.value)
        break
⑤注意:對於函式改成的generator來說,遇到yield返回一個值,遇到return或者最後一行語句,整個指令結束 呼叫函式時,獲得的是函式的return:a = abs(-2) 呼叫函式改成的generator時,獲得的是一個generator物件:g = fib(5)

5.迭代器

①可以直接作用於for...in迴圈的資料型別有 集合資料型別:str、tuple、dict、list、set等 generator:包括生成器帶yield的generator function 稱為可迭代物件:Iterable 可以使用isinstance()判斷一個數據型別是否是Iterable物件
from collections import Iterable

print(isinstance(123, Iterable)) #整數是否可迭代?False
print(isinstance('abc', Iterable)) #str是否可迭代?True
print(isinstance([1, 2, 3], Iterable)) #list是否迭代?True
print(isinstance((1, 2, 3), Iterable)) #tuple是否可迭代?True
print(isinstance({'a' : 1, 'b' : 2, 'c':3}, Iterable)) #dict是否可迭代?True
print(isinstance(set([1, 2, 3]), Iterable)) #set是否可迭代?True
②可以被next()函式呼叫並不斷返回下一個值的物件稱為迭代器:Iterator 可以用isinstance()判斷一個物件是否是Iterator物件:
from collections import Iterator

print(isinstance((x for x in range(10)), Iterator)) #生成器是不是Iterator物件?True
print(isinstance([], Iterator)) #list是不是Iterator物件?False
print(isinstance({}, Iterator)) #dict是不是Iterator物件?False
print(isinstance('abc', Iterator)) #str是不是Iterator物件?False 
生成器都是iterator物件,list、dict、str等雖然是iterable,但不是iterator ③把list、dict、str等Iterable變成iterator可以用iter()函式:
from collections import Iterator

print(isinstance(iter([]), Iterator)) #將list轉化為iterator,Ture
print(isinstance(iter('abc'), Iterator)) #將str轉化為iterator,Ture
④Iterator物件表示的是一個數據流,iterator物件可以被next()函式呼叫並不斷返回下一個資料,直到沒有資料是丟擲StopIteration錯誤。可以把這個資料流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函式實現按需計算下一個資料,所以Iterator的計算是惰性的,只有在需要返回下一個資料時它才會計算。Iterator甚至可以表示一個無限大的資料流,例如全體自然數