版權聲明

所有的部落格文章都可以在右邊[blog文章原始檔案]下載最原始的文字檔案,並依你高興使用 docutil 工具轉換成任何對應的格式方便離線閱覽,除了集結成書販賣歡迎任意取用,引用

generator (pep255 pep289 note)

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)

沒有留言:

Related Posts with Thumbnails