好程式設計師Python培訓分享函數語言程式設計之匿名函式

好程式設計師發表於2020-07-28

   好程式設計師Python 培訓分享函數語言程式設計之匿名函式 在定義函式的時候,不想給函式起一個名字。這個時候就可以用lambda 來定義一個匿名函式 ; 匿名函式又稱之為高效函式 ; 因為在宣告的時候可以直接呼叫(不需要先宣告定義然後再呼叫)。

   語法

   lambda 變數名 ....: 語句表示式

   特點

   a. 宣告時沒有函式名 ( 減少程式設計師對函式名的定義 )

   b. 使用 lambda 關鍵字

   舉個例子

   * 建立一個不帶參匿名函式

   func1 = lambda: 1 == 2

   res = func1()

   print(res)

   # 輸出結果為 False

   * 建立一個傳遞多個引數匿名函式

   func2 = lambda x, y, z: x + y + z

   res = func2(1, 2, 3)

   print(res)

   # 輸出結果為 6

   * 建立一個帶 if 判斷的匿名函式

   func3 = lambda x, y: x if x >; y else y

   res = func3(2, 6)

   print(res)

   # 輸出結果為 6

   以上定義不規範,為了更好理解,所以分步定義; 詳細請看下文的誤區說明 ;

   注意

   1. 變數名之間使用逗號隔開 ;

   2. 呼叫時可以直接將 lambda 整體括起來,然後後面新增括號傳入對應的實參 ( 沒有實參則需要帶上括號表示執行該匿名函式,否則返回的是該匿名函式的物件 )

   3. 匿名函式之間是可以相互呼叫和巢狀的

   作用

   1. 程式一次行使用,所以不需要定義函式名,節省記憶體中變數定義空間

   2. 如果想讓程式更加簡潔時

   匿名函式幾個規則

   1. 一般也就一行表示式,必須有返回值

   2. 不能有 return

   3. 可以沒有引數,可以有一個或多個引數

   匿名函式大量例項

   A. 使用 max 函式求字典的最大值

   dict1 = {'age1': 12, 'age2': 13, 'age3': 14}

   res = max(dict1, key=lambda x: dict1[x])

   print(res)

   B. 使用 filter 過濾字串是否以某個字母開頭

   Names = ['Anne', 'Amy', 'Bob', 'David', 'Carrie', 'Barbara', 'Zach']

   B_Name= filter(lambda x: x.startswith('B'),Names)

   B_Name

   # 輸出結果為: ['Bob', 'Barbara']

   C.lambda map,filter 聯合使用

   squares = map(lambda x:x**2,range(10))

   filters = filter(lambda x:x>;5 and x<;50,squares)

   print(filters)

   # 輸出結果為: [9, 16, 25, 36, 49]

   D.lambda sorted 聯合使用

   death = [ ('James',32),('Alies',20),('Wendy',25)]

   sorted(death,key=lambda age:age[1])

   # 按照第二個元素,索引為 1 排序

   # 輸出結果為: [('Alies', 20), ('Wendy', 25), ('James', 32)]

   E.lambda reduce 聯合使用

   list1 = [1,2,3,4]

   sum = reduce(lambda x,y:x+y,list1)

   print(sum)

   # 輸出結果為: 10

   F. 求兩個列表元素的和

   a = [1,2,3,4]

   b = [5,6,7,8]

   map(lambda x,y:x+y, a,b)

   # 輸出結果為: [6, 8, 10, 12]

   使用誤區

   1 . 給匿名函式命名

   PEP 8 中建議我們不要寫類似下面的程式碼

   func1 = lambda: 1 == 2

   匿名函式可以直接當做變數一樣傳遞,比如傳給函式作為引數,並不要求它一定有個名字。需要注意的是,其實上面的操作並沒有真正起到給函式命名的作用。

   2. 沒有必要的匿名函式

   某些時候,我們沒有使用匿名函式的必要,但卻無意中使用了。一般有兩種情況。一是使用無意義的呼叫,比如下面的程式碼

   res=sorted(list1,key=lambda x:len(x))

   將列表按元素的長度進行排序

   其實,我們可以直接使用

   res=sorted(list1,key=len)

   上面的一提出來大家馬上就理解了,但是平時我們卻或多或少的犯了類似的毛病。另一方面,有很多函式,標準庫中都已經實現了,我們不知道,所以做了多餘的事情。

   3. 降低可讀性的匿名函式

   按元素的長度和字典序對列表進行排序

   list1=["abc","bcde","mhjk"]

   res=sorted(list1,key=lambda x:(len(x),x.upper()))

   上面的程式碼能夠實現功能,但是我覺得下面的可讀性更強一些

   def get_len_upper(x):

   return len(x),x.upper()

   list1=["abc","bcde","mhjk"]

   res=sorted(list1,key=get_len_upper)

   我們透過函式函式名就大概知道了函式的作用,如果是匿名函式的話,我們還得去看相應的邏輯。

   4. 可能根本不需要傳遞函式

   對一個列表進行求和,我們可能會看到這樣的程式碼

   from functools import reducedata=[1,2,3,4,5]

   res=reduce(lambda x,y:x+y,data)

   print(res)

   其實,直接使用sum 函式就可以了

   data=[1,2,3,4,5]

   print(sum(data))

   對於一些特定的需求,很多時候 Python 可能已經有了現成的方案。我們要有這方面的意識,儘可能簡單的去解決問題。

   5. 可以不使用 map/filter

   Python 中的 map filter 一般都結合匿名函式在使用,前者是在迭代過程中對元素做一些處理,後者是過濾掉一些元素。很多情況下,我們可以使用列表推導式或者生成器表示式代替它們。

   用生成器表示式代替 map

   data=[1,2,3,4,5]

   res=map(lambda x:x**2,data)

   # 等價於

   res2=(x**2 for x in data)

   用生成器表示式代替 filter

   data=[1,2,3,4,5]

   res=filter(lambda x:x>;3,data)

   # 等價於

   res2=(x for x in data if x>;3)

   明顯的可以看出,使用生成器表示式的程式碼可讀性更強一些。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913864/viewspace-2707468/,如需轉載,請註明出處,否則將追究法律責任。

相關文章