1. 程式人生 > >Python的匿名函式——lambda

Python的匿名函式——lambda

今天看YATE內嵌Python的例子,竟然又一次忘記了lambda到底是個什麼東東,too faint!特標記如下。

例子:

def route(yate):

    def on_route(route):

        ...



    yate.onmsg("call.route",

        lambda m : m["called"] == "ivr").addCallback(on_route)
在python中使用lambda來建立匿名函式。lambda來源於LISP語言。lambda的形式如下:
  • lambda arg1,arg2... : <expression>
lambda會建立一個函式物件,但不會把這個函式物件賦給一個識別符號,而def則不同,它在建立函式物件的同時會進行這種操作。這是lambda的第一個特點。lambda的第二個特點是,它只是一個表示式,而不是一個語句。如果單獨使它成為了一個語句,比如:
  • lambda x: print x
如果你在你的python程式中寫下了這麼一行,那麼毫無意義,這一行程式碼會建立一個函式物件,但馬上又給丟棄了,因為你沒有使用它的返回值,即那個函式物件。也正是由於lambda只是一個表示式,它可以直接作為list或dictionary的成員,比如:
  • L = [lamba x: x**2, lambda x: x**3]
在這個地方沒有辦法用def語句直接代替。第三,lambda表示式在“:”後只能有一個表示式。也就是說,在def中,可以放在return後的也可以放在lambda,不能放在return後也不能放在這裡。更本質地說,後面的表示式是能夠返回一個值的,不能返回值的不能放在這裡。因此,像if或for或print這種語句就不能用於lambda中,lambda一般只用來定義簡單的函式。當然,通過一些技巧,可以在lambda中實現與if或for相同的功能。比如:if語句可以利用and和or這兩個邏輯操作符的“短路”特性來模擬,比如:
  • ((test and [x]) or [y])[0]
這樣的話,如果test為真,那麼就會計算[x],當然得到的就是[x],由於在or操作符的左邊已經得到真值,or的右邊就不會被計算,因此得到的是[x][0],最後的結果是x。如果test為假,那麼根據and的特性,左邊已經為假,右邊不會被計算。這時or的左邊為假那麼就得到[y][0],最後的結果是y。注意在這裡不能寫成如下的形式:
  • (test and x) or y
在x為真值時,這種形式與上面這種形式是等價的。但設想這種情況,“如果test為真,則取0,如果test為假,則取[]”,也就是說x本身是一個假值,用上面的形式書寫就是:
  • (test and 0) or []
顯然不能達到目的,這個式子永遠只會取到[]。因此應該改寫成:
  • ((test and [0]) or [[]])[0]
在lambda中迴圈語句也是可以模擬的,用的是map函式。比如:
  • F=lambda x: map((lambda y: y**2), x)
當然,這種東西看起來就很複雜,如果可能最好不要巢狀使用lambda。print也是可以模擬的:
  1. import sys
  2. pp = lambda x: sys.stdout.write(str(x)+'/n')
  3. pp(8) ===> 8