Simple Generator
Python再 PEP255 導入了Generator的概念,並引入新的keyword yield.
重點筆記
- yield 必須再function中
- 執行到 yield 時, function的狀態會被保留下來(local variable),所以下一次iterate 會直接繼續往下執行.
- yield 不能放在try/final block的try clause中,因為python無法保證final一定會被執行.
- function 中包含 yield 敘述則該function為generator function, 並提供了標準iterator能力.
- exception(包含StopIteration) 會讓generator function結束iteration.
# g()的yield 42永遠執行不到,因為yield f() # 丟出exception造成generator function'死亡' >>> def f(): ... return 1/0 >>> def g(): ... yield f() # the zero division exception propagates ... yield 42 # and we'll never get here >>> k = g() >>> k.next() Traceback (most recent call last): File "" , line 1, in ? File "" , line 2, in g File "" , line 2, in f ZeroDivisionError: integer division or modulo by zero >>> k.next() # and the generator cannot be resumed Traceback (most recent call last): File "" , line 1, in ? StopIteration >>>
- yield可以放到 finally clauses, except clauses, or in the try clause of a try/except construct.
Generator Expression
generator expressions as a high performance, memory efficient generalization of list comprehensions and generators .
下面的list comprehensions會再記憶體中建立完整的list
sum([x*x for x in range(10)])
使用Generator expression只有再每次iteration呼叫next()的時候分配記憶體保留next()的回傳值,下面是一個和上例等值的 generator expression版本.
sum(x*x for x in range(10))
類似的優點是使用再container的constructor上.
s = Set(word for line in page for word in line.split())
d = dict( (k, func(k)) for k in keylist)
Cenerator expression特別適合使用再 max(), sum() 和 min() 這類function上面.
# 計算最一行中最多的字數
max(len(line) for line in file if line.strip())
也可以簡化lamba()
reduce(lambda s, a: s + a.myattr, data, 0)
reduce(lambda s, a: s + a[3], data, 0)
# 等於下面
sum(a.myattr for a in data)
sum(a[3] for a in data)
沒有留言:
張貼留言