1. 程式人生 > >python 學習彙總35:生成器-generator( tcy)

python 學習彙總35:生成器-generator( tcy)

 生成器-generator 2018/7/7

 生成器是一個函式,生成一個值的序列,用在迭代和容器 1.1性質
1) 生成器是迭代器儲存是演算法,每次迭代返回一個值,遇到StopIteration結束
2) 生成器函式跟普通函式區別:
把return換成yield,yield內部實現迭代器協議,同時保持狀態可以掛起。
yield是資料生產者,諸如for等是資料消費者
3)生成器執行 :
next,for ,檢索生成器元素如list(generator), 當需要資料時才會執行。
4)值傳遞給生成器
val=(yield i)括號不是必要;yield表示式必須加括號val=(yield i)+12

1.2.定義yield element
任何使用yield的函式都成為生成器。呼叫生成器函式將建立一個物件

 

生成器屬性
屬性
g.gi_code 生成器函式程式碼物件
g.gi_frame 生成器函式的執行幀
g.gi_running 顯示生成器函式目前是否真正執行的整數

方法
g.__next__(),next() 
執行函式直到遇到下一條yield語句為止,並返回值; 等價於send(None)

g.send(value) 值傳送到生成器;
恢復生成器的程式碼, yield表示式返回指定的值。
如果__next__()呼叫常規方法則yield返回None。

# g.throw(exc,exc_value,exc_tb)語句消耗掉一個yield
g.throw(type, value=None, traceback=None) 在發生器內引發異常;
type=exception傳入一個異常,在當前yield語句處引發

g.close() 
關閉生成器,丟擲GeneratorExit或StopIteration

例項1:send()方法 : 

send 方法:外部作用域訪問生成器 引數(要傳送的“訊息”任意物件)

def gener_fun():
value=0
while True:
new=yield value
if new=='e':
break
value = 'new= %s' % new
# 呼叫:
g=gener_fun()
print(g.send(None))
print(g.send('first'))
print(g.send(2))
try:
print(g.send('e'))
except StopIteration:
print('StopIteration!')

  

例項2:無窮奇數 

def odd(long=1):
n=long
while True:
yield n
n+=2

# 呼叫:
data = odd(1)

for count in data:
if count >=10: break
print(count)#1,3,5,7,9

例項3:遞迴

def fib(max):
n, a, b = 0, 0, 1

while n < max:
yield b
a, b = b, a + b
n = n + 1

例項4:生成器關閉close()

def g4():
yield 1
yield 2
# 呼叫:
g=g4()
next(g) #1
g.close()
next(g) #關閉後,yield 2語句將不再起作用返回異常StopIteration

例項5:工作原理

def generator():
print ('begin=: generator')
i = 0
while True:
print ('before return= ', i )
yield i
i += 1
print ('after return= ', i )
# 呼叫:
g = generator()#generator object
next(g) #開始執行
#begin=: generator
#before return= 0
next(g) #after return= 1
#before return= 1
  另一個例項
throw()後直接丟擲異常並結束程式,或消耗掉一個yield,或在沒有下一個yield的時候直接進行到程式的結尾


def gener_fun():
while True:
try:
yield '1.first...'
yield '2.two...'
print('3.three...')
except ValueError:
print('4.ValueError...')
except TypeError:
break
# 呼叫:
g=gener_fun()
print(next(g))
print(g.throw(ValueError))
print(next(g))
try:
print(g.throw(TypeError))
except StopIteration:
print('5.ValueError...')

# 1.first...
# 4.ValueError...
# 1.first...
# 2.two...
# 5.ValueError...

例項6:2Dlist資料

def data(lst):
for sublist in lst:

for element in sublist:
yield element #每次產生多個值
# 呼叫:
lst = [[1, 2], [3]]
for num in data(lst):
print( num )   
例項:普通函式模擬生成器
def data(lst):
    result = []            #函式體開始處

try:                         # 不要迭代類似字串的物件:
        try: lst + ""
        except TypeError:pass
        else:
            raise TypeError

        for sublist in lst:
            for element in data(sublist):
                result.append(element)   #替換生成器表示式
            
except TypeError:
    result.append(lst)
    return result                               #函式末尾