python 生成器和lambda的故事

今天在思考python表推導的語法的時候,很好奇這樣的結果:

a = [ x for x in [1, 2, 3] ]
b = ( x for x in [1, 2, 3] )

print('a type: {}'.format(type(a)))
print('b type: {}'.format(type(b)))
輸出:

a type: <type 'list'>
b type: <type 'generator'>
感覺[和]兩個符號表示列表,那麼(和)應該表示元組啊。

不過沒有繼續深究下去,因爲我估計要看python源碼,稍後抽個時間看看

既然b是一個生成器,那麼x 應該就是默認的yield x,只不過在表推導的形式裏沒有寫上yield罷了。

那麼改變一下x,換成一個lambda吧

b = ( lambda y : x + y for x in [1, 2, 3] )
print('b type: {}'.format(type(b)))

print(b.next()(1))
print(b.next()(1))
print(b.next()(1))
這樣,每一次都是yield 一個匿名函數,且其函數體中的x爲列表[1, 2, 3]中對應的值

輸出:

b type: <type 'generator'>
2
3
4
也就理所當然了。b.next()返回匿名函數,在後面添加上()就表示調用這個函數,裏面的1對應y的值

那麼匿名函數的參數也是x呢?

b = ( lambda x : x + x for x in [1, 2, 3] )
print('b type: {}'.format(type(b)))

print(b.next()(1))
print(b.next()(1))
print(b.next()(1))
輸出:

b type: <type 'generator'>
2
2
2
看不太明白,再來一個例子:

b = ( lambda x : x + x for x in [1, 2, 3] )
print('b type: {}'.format(type(b)))

print(b.next()(9))
print(b.next()(9))
print(b.next()(9))
輸出:

b type: <type 'generator'>
18
18
18
原來是匿名函數的參數x覆蓋了表推導的參數x,即表推導中:for x in [1, 2, 3]在前面的語句:lambda x : x + x看不見了,無法訪問了

當然了,由於b是生成器,當第四次調用的時候,會拋出StopIteration異常,若想再用,得重新初始化一下了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章