2011-12-08 47 views
4

我在Python中遇到lambda表達式。我已經看到很多簡單的例子(包括SE的例子),其中lambda表達式產生像加法器那樣的函數,但是我看不到它們的實際用途,例如,一些例子,如果沒有lambda表達式,編寫相同的代碼就會很痛苦。例如,lambda在Python中非常有用

你可以在文本處理中展示一些你會使用lambda表達式的東西,這很難避免lambda表達式嗎?但是一些實用的(不是數學遊戲)。

+0

這次重寫一些你自己的命令代碼是功能方式。也許你會明白爲什麼和什麼時候lambdas是有用的;-) –

+2

嚴格來說,列表解析不是lambda表達式的替代。它們更多地代替了'map'和'filter'功能。無可否認,lambda經常與'map'和'filter'一起使用。 – kindall

+0

「難以避免」是什麼意思?當允許多行函數定義被一條單一的更可讀的行替換時,Lambdas非常有用。 http://stackoverflow.com/questions/8363390/how-to-make-tkinter-message-expand-when-i-resize-the-window/8364895#8364895如果沒有lambda,就不會「硬」但它確實更緊湊,更容易。 – Dave

回答

5

在這種情況下,它會一直痛苦寫出來的所有lambda表達式作爲單獨的函數。

這段代碼做了些什麼?將自定義Excel錶轉換爲自定義數據庫表的插入語句。在Excel表格字段和數據庫字段之間存在映射關係,並且在Excel表格字段和要在Excel表格字段中應用的函數之間存在映射,然後將其插入到數據庫中。你並不是真的想爲每個字段定義一個單獨的函數。

map_func = { 'ID' : lambda x : 'mig_farm_seq.nextval', 
      'ENTERPRISE_NAME' : wrap_str, 
      'TAX_NUMBER' : wrap_str, 
      'FAMILY_NAME' : lambda x : wrap_str(x.split()[0]), 
      'GIVEN_NAME' : lambda x : wrap_str(x.split()[1]), 
      'ENTERPRISE_REGISTRATION_NUMBER' : wrap_str, 
      'PREMISE_NAME' : wrap_str, 
      'HOUSE_ID' : wrap_str, 
      'POSTAL_CODE' : wrap_str, 
      'PHONE_NUMBER_1' : lambda x : wrap_str(get_phone_number(x, True)), 
      'PHONE_NUMBER_2' : lambda x : wrap_str(get_phone_number(x, False)), 
      'FAX_NUMBER' : lambda x : wrap_str(x.replace(' ', '')), 
      'BANK_IDENTIFIER' : lambda x : wrap_str(x.replace(' ', '').replace('-', '')[:3]), 
      'BANK_ACCOUNT_NUMBER' : lambda x : wrap_str(x.replace(' ', '').replace('-', '')), 
      'NUMBER_OF_EMPLOYEES' : wrap_null, 
      'SETTLEMENT_NUMBER' : wrap_null, 
      'REGISTRATION_NUMBER' : lambda x : insert_reg_number % x, 
      'GENDER' : wrap_str, 
      'ACTIVITY' : lambda x : '0', 
      'REG_HOLDER_ACTIVITY' : lambda x : '0', 
      'PROCESSED_BY_JOB' : lambda x : '0' 
     } 

來源:http://pastebin.com/MxEPBMaZ

+0

我在現實世界的代碼中多次使用過相同的設計模式。所以+1是一個很好的例子。 –

+1

@bpgergo這是一個很好的例子。我在考慮接受,但會等待約。一天呢。 – xralf

+0

+1 - 很好的例子。我也多次使用這種模式(或者非常類似於它)。 –

4

一個地方,我經常使用它們:的sortsorted功能key功能:

>>> person = lambda name, age: { "name": name, "age": age } 
>>> people = [ person("Joe", 61), person("Jane", 52) ] 
>>> people.sort(key=lambda person: person["age"]) 

這將通過他們的年齡的人的名單排序。

我用lambda表達式的另一個地方是re.sub

>>> re.sub("0x([0-9a-f]+)", lambda match: "0x" + match.group(1).upper(), "0xfa") 
'0xFA' 
+3

對於排序排序鍵,使用'operator。* getter()'通常更清晰/更快/更短/更好。這可以用'people.sort(key = operator.itemgetter(「age」))'來代替。 –

+1

是的,對於簡單的情況,可以使用'operator'模塊......但是IMO在那裏使用lambda是合理的,並且有些情況下'operator'不足(只是爲了ex,如果你想排序的話)名字,名字):'people.sort(key = lambda p:(p [「last_name」],p [「first_name」])' –

0

他們是有用的,當你需要短暫的功能比較兩個項目或執行一些其它的操作,這將作爲參數傳遞,並有沒有必要讓函數具有名稱,因爲它僅用作參數。

他們是有用的,當函數,寫成一個lambda,比def行,你通常會用它來命名,並在較短您return將在年底使用。

當你想要部分應用一個函數時,它們很有用 - 即你有一個函數需要傳遞到別的地方,並且希望提供一些或所有參數給傳遞的函數而不用實際調用它。 Lamdda可以讓您做到這一點,而無需爲每個需要的變體定義和命名單獨的函數。

+0

這是我已經知道的,但是一些例子表明lambda表達式是不可或缺的,而且這個例子應該做一些有用的事情(不僅僅是數學遊戲) – xralf

+2

它們不是必不可少的;畢竟它們只是一個函數,你可以在沒有lambda的情況下整天編寫函數。 – kindall

+0

也許'不可或缺'是一個很強的詞,我還沒有看到這個例子,我會說:「沒有lambda表達式,這會很糟糕。」 – xralf

0

我所有的Django的項目包括2串(settings.py):

DIRNAME = os.path.dirname(__file__) 
_rel = lambda x: os.path.join(DIRNAME, x) 
2

而不是暗示任何在這裏我建議訪問您安裝Python和grep的lib目錄lambda。你會得到足夠的例子來滿足你的胃口。

+0

非常好的建議。爲此,我將添加以下內容:「嘗試使用lambda結構將代碼重寫爲不使用它們的代碼,然後比較這兩個版本。也許這將幫助您看到案例中lambda的有用性(或無用)逐案基礎「。 –

+0

@Ahhijit請更具體一點。許多文件沒有lambda或只有少數。 – xralf

0

一種情況下他們是真正有用的:

假設你正在使用PyQt的,它允許您連接信號的其他插槽(方法)。有時候,我需要執行某個動作,而不是寫一個函數,所以我需要的只是一次性函數。

obj.signal.connect(lambda: doFoo(bar)) 

當然,這是對比:

def doBoo(): 
    return doFoo(bar) 
obj.signal.connect(doBoo) 

..更清潔的前一種方法。

1

既然你已經問過關於文本處理,看看this的例子(和this one是類似的)。

閉包幾乎總是比對象更容易處理(因爲隱式地捕獲環境),但對於那些在OOP方面思考的人來說並不那麼明顯。我建議試着學習至少一種體面的函數式語言(python中的lambda表達式太有限),這樣你就可以理解如何將這些技術有效地應用於像Python這樣的語言。