Python中Lambda使用要注意的幾個地方

安全劍客發表於2020-04-16
lambda被認為是非常Python的語言,是Python程式設計中比較受歡迎的功能之一。 如此之多,以至於許多Python程式設計師都想盡可能地使用它們。

lambda被認為是非常Python的語言,是Python程式設計中比較受歡迎的功能之一。 如此之多,以至於許多Python程式設計師都想盡可能地使用它們。

Python中Lambda使用要注意的幾個地方Python中Lambda使用要注意的幾個地方

當然,lambda具有使我們的程式碼簡潔的優勢,但是在專案中過度使用它們會導致濫用,從而降低我們程式碼的可讀性和可維護性。

在開始研究這些誤用是什麼之前,讓我們先快速回顧一下lambda。 如果您對它們非常瞭解,則可以跳到下一部分。

Lambda,也稱為lambda函式,是匿名函式,可以接受任意數量的引數,而只有一個表示式。 它們的宣告由lambda關鍵字表示。 基本語法如下。

lambda arguments: expression

Lambda最適合需要小的功能且僅使用一次的地方。 lambda的一種常見用法是將其設定為內建sorted()函式中的關鍵引數。 這是一個例子。

>>> students = [('Mike', 'M', 15), ('Mary', 'F', 14), ('David', 'M', 16)] 
>>> sorted(students, key=lambda x: x[2]) 
[('Mary', 'F', 14), ('Mike', 'M', 15), ('David', 'M', 16)] 
# The students are sorted by age

許多教程在解釋lambda是什麼以及可以在哪裡使用lambda方面做得很好,因此,沒有充分的理由在這裡重複大量的講解。

相反,本文的目的是向您展示最常見的lambda誤用,以便在以下所列情況以外的其他情況下使用lambda時,您可能會正確使用它們。

1.重新發明輪子

lambdas的第一個誤用是忽略了現有的內建函式。

讓我們仍然以sorted()函式為例。 假設我們有一個字串列表,我們想使用它們的長度對它們進行排序。

當然,lambda函式lambda x:len(x)可以工作,但是直接使用內建的len()函式怎麼樣?

>>> pets = ['dog', 'turtle', 'bird', 'fish', 'kitty'] 
>>> sorted(pets, key=lambda x: len(x)) 
['dog', 'bird', 'fish', 'kitty', 'turtle'] 
# The built-in len() function 
>>> sorted(pets, key=len) 
['dog', 'bird', 'fish', 'kitty', 'turtle']

這是另一個涉及使用max()函式的示例。

>>> number_tuples = [(4, 5, 7), (3, 1, 2), (9, 4, 1)] 
>>> sorted(number_tuples, key=lambda x: max(x)) 
[(3, 1, 2), (4, 5, 7), (9, 4, 1)] 
# The built-in max() function 
>>> sorted(number_tuples, key=max) 
[(3, 1, 2), (4, 5, 7), (9, 4, 1)]

優秀實踐1:在編寫自己的Lambda之前先考慮一下內建函式。

2.將其分配給變數

在一些教程(包括我的一些教程)中,我已經看到了將lambdas分配給變數的方法,但是它主要是向初學者展示lambdas本質上是函式。

但是,某些初學者可能已將其作為一種好習慣,並認為lambda只是宣告短函式的便捷方式。 以下程式碼片段向您展示了這種濫用。

>>> divide_two_numbers = lambda x, y: x / y 
>>> divide_two_numbers(4, 5) 
0.8

為什麼要避免這種情況? 如果您還記得上面提到的內容,那麼lambda應該只使用一次,因此沒有理由將lambda分配給變數。

如果確實需要使用相關功能,則應使用def關鍵字來宣告一個常規函式,如下所示。

如果您認為使用此簡單功能的兩行程式碼並不酷,我們可以將其重寫為一行:defdivid_two_numbers_fun(x,y):返回x / y,其工作方式相同。

>>> def divide_two_numbers_fun(x,y):  
...     return x / y 
...  
>>> divide_two_numbers_fun(7, 8) 
0.875

避免為變數分配lambda的主要原因是出於除錯/維護的目的,尤其是在生產/團隊合作環境中。

讓我們看一個簡單的例子,可能發生的事情。 在實際情況下,事情可能會變得複雜得多。

>>> divide_two_numbers(3, 0) 
Traceback (most recent call last): 
  File "", line 1, in  
  File "", line 1, in  
ZeroDivisionError: division by zero 
>>> divide_two_numbers_fun(3, 0) 
Traceback (most recent call last): 
  File "", line 1, in  
  File "", line 1, in divide_two_numbers_fun 
ZeroDivisionError: division by zero

如您在上面看到的,透過常規函式的宣告,我們確切地知道哪個函式導致了錯誤。 相比之下,使用lambda只能告訴我們存在一個lambda導致錯誤。

為什麼沒有顯示功能名稱?

這是因為lambda是匿名函式,所有這些函式都具有相同的名稱-。 您能想象如果您的同事發現數十個存在錯誤會多麼令人沮喪?

優秀實踐2:要多次使用常規函式而不是lambda。

3.高階函式使用不當

當我們說高階函式時,是指可以透過將函式作為引數或透過返回函式來對其他函式進行操作的函式。

與當前主題相關的函式是map(),filter()和reduce(),它們在lambda的許多教程中都已或多或少地被使用。 但是,這導致對lambda以及更高階函式的某種濫用。

出於演示目的,我將在本教程中僅使用map()函式,但相同的原理也適用於其他高階函式。

假設我們有一個整數列表,並且希望有一個包含它們的平方的列表。 下面將lambda與map()函式一起使用。

我們將獲得一個迭代器-map()函式中的map物件,然後將其轉換為列表,我們需要在此迭代器上呼叫list()函式。

>>> numbers = [1, 2, 3, 5, 8] 
>>> squares = list(map(lambda x: x * x, numbers)) 
>>> squares 
[1, 4, 9, 25, 64]

實際上,可以透過列表理解方便地實現相同的功能-不需要高階函式或lambda。 更加簡潔易讀,不是嗎?

當然,掌握列表理解能力是另一個" Pythonic功能"主題,需要另一個教程。

>>> numbers = [1, 2, 3, 5, 8] 
>>> squares = [x * x for x in numbers] 
>>> squares 
[1, 4, 9, 25, 64]

優秀實踐3:考慮使用帶列表推導的lambda替換高階函式。

4.表示式太笨拙

這比以前的方法少見。 但是一些程式設計師只是儘可能地使用lambda來努力編寫最多的Python程式碼。 有時需要付出一定的代價-可讀性。

假設我們有一個字串列表,我們需要使用一個奇怪的要求對它們進行排序:單詞中不同母音的數量。 在sorted()函式中使用lambda如下所示。

>>> texts = ['iiiii', 'bag', 'beto', 'blackboard', 'sequoia'] 
>>> sorted(texts, key=lambda x: len(set([l for l in list(x) if l in ['a','e','i','o','u']]))) 
['iiiii', 'bag', 'beto', 'blackboard', 'sequoia']

它可以按預期工作,但絕對不是最易讀的程式碼。 下面的程式碼怎麼樣?

>>> texts = ['iiiii', 'bag', 'beto', 'blackboard', 'sequoia'] 
>>> def number_distinct_vowels(x): 
...     vowels = ['a', 'e', 'i', 'o', 'u'] 
...     vowels_only = [l for l in list(x) if l in vowels] 
...     distinct_vowels = set(all_vowels) 
...     return len(distinct_vowels) 
...  
>>> sorted(texts, key=number_distinct_vowels) 
['iiiii', 'bag', 'beto', 'blackboard', 'sequoia']

當然,我們需要再寫幾行程式碼,但是新程式碼難道不具有更好的可讀性嗎?

優秀實踐4:如果lambda的表示式過於繁瑣,則編寫一個正則函式。

總結

Lambda一直是Python初學者的硬主題之一,他們一開始就不惜一切代價避免使用它們。

一段時間後,當恐懼消失時,他們開始學習lambda,並發現自己一點也不難。 然後,它們開始使用lambda,但不幸的是,有些人可能過多地使用了lambda,導致如上所述的各種濫用。

我希望本文可以幫助解決其中一些問題。

透過避免這些誤用並遵循優秀實踐技巧,我敢打賭,正確使用lambda的Python程式碼將具有更好的可讀性和可維護性。

原文地址:

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

相關文章