Hướng dẫn này giải thích Hàm Lambda của Python là gì, cách thức và thời điểm sử dụng hàm này với các ví dụ. Cũng so sánh các hàm Thông thường và Lambda
Hàm ẩn danh, thuật ngữ thường được sử dụng trong lập trình máy tính, còn được gọi là hàm lambda là một tính năng của nhiều ngôn ngữ lập trình kể từ năm 1958, bắt nguồn từ việc phát minh ra phép tính lambda của Alonzo Church
Ngày nay, một số lượng lớn ngôn ngữ lập trình hỗ trợ Hàm ẩn danh hoặc có các thư viện đã được tạo để cung cấp hỗ trợ
=> Kiểm tra TẤT CẢ các hướng dẫn về Python tại đây
Bạn sẽ học được gì
Hàm Lambda là gì
Nói chung, một chức năng ẩn danh là một chức năng không có tên. Trong Python, một hàm ẩn danh được tạo bằng từ khóa lambda, do đó đôi khi được gọi là hàm lambda, biểu thức lambda, v.v. Trong các ngôn ngữ lập trình khác, chúng được gọi khác nhau
Đề nghị đọc =>> Lambdas trong C++
Ngôn ngữ lập trình và cách các chức năng ẩn danh của chúng được đặt tên
Ngôn ngữ lập trìnhTênRuby, Smalltalk, C, C++BlocksSwiftsClosuresCOBOPhương pháp ẩn danh
Trong Python, hàm lambda có cú pháp đơn giản, nhưng không giống như các ngôn ngữ được hỗ trợ khác như Haskell, nó chỉ giới hạn ở một biểu thức thuần duy nhất trong phần thân của nó. Có nghĩa là, nó không thể thực hiện các phép gán hoặc sử dụng các câu lệnh như while, for, raise, return, assert, v.v.
Điều này không có gì ngạc nhiên vì ban đầu, Python không cho phép các câu lệnh trong biểu thức của nó và lambda là một biểu thức
Mặc dù nhiều người đam mê Python đã đề xuất rằng các hàm lambda của Python được tăng cường để hỗ trợ các câu lệnh và những người khác cho rằng nó vô dụng vì các hàm thông thường đã có sẵn cho sự phức tạp như vậy
cú pháp
Một hàm lambda có cú pháp sau
lambda arg1[, arg2,...,argN] : expressionNhư đã thấy trong cú pháp ở trên, hàm lambda có thể có nhiều tham số (được phân tách bằng dấu phẩy và không có dấu ngoặc đơn) nhưng chỉ có một biểu thức Python hợp lệ duy nhất được ước tính và trả về mà không cần sử dụng câu lệnh return một cách rõ ràng, nhân tiện thì không
NB. Dấu ngoặc vuông chỉ ra rằng các đối số khác là tùy chọn
Hãy xem xét một số ví dụ sử dụng trình bao tương tác Python
Ví dụ 1. Xác định hàm lambda cộng hai giá trị.
>>> (lambda a,b: a+b)(2,4) # apply the function immediately 6 >>> add = lambda a,b: a+b # assign the function to a variable >>> add(2,4) # execute the function 6NB. Chúng ta cần lưu ý những điều sau
- Áp dụng một chức năng ngay lập tức được gọi là IIFE, viết tắt của Thực thi chức năng được gọi ngay lập tức
- Gán một hàm lambda cho một biến là một cách làm không tốt (sẽ nói thêm về điều này sau)
Đoạn mã trên có các phần sau
Như đã thấy trong hình trên, từ khóa lambda tạo biểu thức lambda. Hai tham số được xác định và nhận bất kỳ hai đối số nào và chuyển chúng vào biểu thức python đơn được xác định sau dấu hai chấm (. )
Đối số trong Hàm Lambda
Khi nói đến đối số, không có sự khác biệt giữa hàm lambda và hàm thông thường. Các hàm lambda hỗ trợ tất cả các cách truyền đối số được các hàm thông thường hỗ trợ. Xem Hàm Python để biết thêm về các đối số của Hàm
Ví dụ 2. Xác định hàm lambda với các cách truyền đối số khác nhau.
>>> (lambda a,b,c=2: a+b+c)(2,3,5) # positional and default parameters 10 >>> (lambda a,*args: a + sum(args))(3,4,2,7,8) # positional and arbitrary positional parameter 24 >>> (lambda **kwargs: sum(kwargs.values()))(a=3,b=9,c=8) # arbitrary keyword parameter 20 >>> (lambda a, *, b: a+b)(3,b=9) # positional and keyword-only parameter 12Hàm Lambda và hàm thông thường
Tóm lại, hàm lambda là hàm không có tên và đôi khi được gọi là hàm ẩn danh, biểu thức lambda
Trong phần này, chúng ta sẽ xem xét một số điểm giống và khác nhau giữa hàm lambda và hàm thông thường (hàm được xác định bằng từ khóa def)
Sự khác biệt giữa Hàm Lambda và Hàm thông thường
Sự khác biệt giữa Hàm Lambda và Hàm thông thường
Lambda FunctionChức năng thông thườngNó được tạo bằng từ khóa lambda. Nó được tạo bằng từ khóa def. Traceback xác định một chức năng lambda là. Traceback xác định một chức năng thông thường theo tên của nó. Thường được viết dưới dạng mã một dòng. Có thể chứa mã nhiều dòng. Có thể được gọi ngay lập tức (IIFE). Không thể được gọi ngay lập tức. Không bị ràng buộc bởi một cái tên. Nó bị ràng buộc bởi một cái tên. Không hỗ trợ chú thích. Hỗ trợ chú thích. Phải có duy nhất một biểu thức. Có thể có nhiều biểu thức. Không hỗ trợ tuyên bố. Hỗ trợ báo cáo. Không được chứa câu lệnh return, nhưng tự động trả về phần thân của nó. Phải chứa câu lệnh return để trả về giá trị. Trả về Không nếu không có câu lệnh trả về nào
Bảng trên tóm tắt sự khác biệt giữa lambda và hàm thông thường. Tuy nhiên, chúng tôi sẽ giải thích thêm về những điểm đó trong phần này
#1) Sự khác biệt trong từ khóa
Đây là một trong những khác biệt cơ bản và quan trọng. Hàm lambda được xác định bằng từ khóa lambda, khác với hàm thông thường sử dụng từ khóa def
Từ khóa lambda tạo và trả về một đối tượng trong khi từ khóa def tạo và liên kết đối tượng với tên của hàm
Ví dụ 3. Sự khác biệt về từ khóa giữa Lambda và Hàm thông thường.
lambda keyworddef keyword# xác định hàm lambda với từ khóa 'lambda' và chỉ định.
thêm = lambda a, b. a + b
# gọi hàm và in kết quả
print(add(4,5))# xác định hàm thông thường với từ khóa 'def'
def add(a, b): return a + b
# gọi hàm và in kết quả
print(add(4,5))Output
#2) Sự khác biệt trong Tracbacks
One of the reasons why lambda functions are not highly recommended is because of the way traceback identifies them. We shall see that, when an exception gets raised in a lambda function, the traceback will identify it as . This can be hard to debug as it’ll be difficult to locate the specific lambda function in question.
Traceback xác định các chức năng thông thường khác nhau và phù hợp hơn theo tên. Điều này làm cho chúng rất được ưa chuộng trong quá trình gỡ lỗi
Ví dụ 4. Kích hoạt ngoại lệ và xem dấu vết khác nhau như thế nào trong việc xác định chúng.
Sự khác biệt về nhận dạng truy nguyên giữa Lambda và hàm Thông thường
lambda tracebackdef tracebackdivide = lambda a,b. a/b
# chia cho 0 để tăng ngoại lệ 'ZeroDivisionError'
divide(3,0)defdivide(a,b).
return a/b
# chia cho 0 để tăng ngoại lệ 'ZeroDivisionError'
divide(3,0)Output) để đặt siêu dữ liệu cho giá trị trả về. Điều này không làm cho nó phù hợp với các hàm lambda vì chúng không sử dụng dấu ngoặc đơn để đặt đối số và chỉ hỗ trợ một biểu thức duy nhất
Kiểm tra bài viết về Tài liệu và Hướng nội hàm Python để biết thêm về các chú thích hàm
#7) Sự khác biệt trong cách diễn đạt
Không giống như các hàm thông thường, hàm lambda chỉ hỗ trợ một biểu thức duy nhất. Mặc dù hàm lambda có thể được biểu thị bằng mã nhiều dòng như trong ví dụ 5 và nó vẫn là một câu lệnh đơn
#8) Sự khác biệt trong Tuyên bố
Trong Python, các câu lệnh là các hành động hoặc hướng dẫn có thể được thực thi và hầu hết được tạo thành từ các từ khóa dành riêng như return, raise, if, for. Trong Python, chúng ta không thể có câu lệnh bên trong biểu thức. Đây là lý do tại sao một hàm lambda không thể hỗ trợ các câu lệnh vì bản thân nó là một biểu thức
Hàm lambda không hỗ trợ câu lệnh trả về nhưng tự động trả về kết quả của biểu thức. Mặt khác, một hàm thông thường yêu cầu một câu lệnh return để trả về một giá trị. Hàm thông thường không có câu lệnh trả về sẽ tự động trả về Không có
Hãy kiểm tra xác nhận quyền sở hữu này trong ví dụ dưới đây
Ví dụ 7. Kiểm tra đối tượng trả về của hàm thông thường không có câu lệnh trả về.
>>> def a(): .. pass # pass statement. Does nothing. .. >>> b = a() # execute our function and assign the return value. >>> b == None # compare to 'None' TrueĐiểm giống nhau giữa hàm Lambda và hàm thông thường
Xét cho cùng, chức năng Lambda chỉ là một chức năng. Mặc dù chúng có một số điểm khác biệt mà chúng ta đã thấy ở trên, nhưng chúng cũng có một số điểm tương đồng. Trong phần này, chúng ta sẽ xem xét một số điểm tương đồng của chúng
#1) Thực thi bởi Trình biên dịch
Tóm lại, hàm lambda và hàm thông thường với một câu lệnh trả về duy nhất có cùng mã byte do trình biên dịch tạo ra trong quá trình thực thi
Như chúng tôi đã đề cập ở trên, hàm lambda chỉ là một hàm. Chúng tôi có thể xác minh khiếu nại này bằng chức năng tích hợp như bên dưới
Ví dụ 8
>>> add = lambda a, b: a + b >>> type(add) <class 'function'>Để xác minh sự tương đồng trong mã byte, chúng ta có thể sử dụng mô-đun dis như bên dưới
Ví dụ 9
>>> add = lambda a, b: a + b # define our lambda function >>> def add2(a,b): return a + b # define our regular function .. >>> import dis # import the dis module >>> dis.dis(add) # introspect the lambda function bytecode 1 0 LOAD_FAST 0 (a) 2 LOAD_FAST 1 (b) 4 BINARY_ADD 6 RETURN_VALUE >>> dis.dis(add2) # introspect the regular function bytecode 1 0 LOAD_FAST 0 (a) 2 LOAD_FAST 1 (b) 4 BINARY_ADD 6 RETURN_VALUE >>>#2) Lập luận
Như chúng ta đã thấy ở trên, hàm lambda chỉ là một hàm. Do đó, nó hỗ trợ các cách truyền đối số giống như các hàm thông thường. Kiểm tra ví dụ 2 thể hiện các đối số trong các hàm lambda
#3) Người trang trí
Trình trang trí là một tính năng trong Python cho phép chúng ta thêm chức năng mới vào một đối tượng mà không cần thay đổi cấu trúc ban đầu của nó. Tính năng này rất phổ biến trong thực tế, vì vậy chắc chắn rằng hàm lambda sẽ hỗ trợ tính năng như vậy
Mặc dù nó hỗ trợ các bộ trang trí, nhưng nó không sử dụng cú pháp @ để trang trí mà chỉ gọi hàm lambda
Ví dụ 10
________số 8đầu ra
NB: Though the lambda function is assigned to a variable(bad practice), it is not bound to that variable. Hence, it is identified by
#4) Làm tổ
Hàm lambda có thể được lồng vào nhau vì nó chỉ là một hàm. Tuy nhiên, nó rất hiếm do những hạn chế của nó (biểu thức đơn, không có câu lệnh, v.v.)
Bất cứ khi nào cần một biểu thức đơn giản, hàm lambda có thể được sử dụng thay vì liên kết một biến với câu lệnh def. Tuy nhiên, chúng tôi khuyên bạn nên sử dụng câu lệnh def cho mục đích dễ đọc và gỡ lỗi
Ví dụ 11
def enclosing_func(a): # nesting a lambda function return lambda b: a + b if __name__ == "__main__": # execute enclosing function which returns the nested lambda function. add3 = enclosing_func(3) print(add3(32)) print(add3(2))đầu ra
Khi Nào Nên Sử Dụng Các Hàm Lambda
Như đã nêu ở trên, hàm lambda là một hàm không có tên. Nói như vậy, lý do quan trọng nhất để sử dụng hàm lambda là khi chúng ta chỉ cần hàm đó một lần và nó chỉ yêu cầu một biểu thức duy nhất
Hầu hết các hàm lambda này được sử dụng trong các hàm tích hợp bậc cao hơn như map(), filter(), reduce(), sorted(), min(), v.v. dưới dạng đối số hoặc giá trị của thuộc tính khóa
Ví dụ 12. Sắp xếp danh sách các số nguyên bằng hàm sorted().
>>> (lambda a,b: a+b)(2,4) # apply the function immediately 6 >>> add = lambda a,b: a+b # assign the function to a variable >>> add(2,4) # execute the function 6 0Ví dụ 13. Chỉ lọc ra các số lẻ trong danh sách.
>>> (lambda a,b: a+b)(2,4) # apply the function immediately 6 >>> add = lambda a,b: a+b # assign the function to a variable >>> add(2,4) # execute the function 6 1NB. Danh sách hiểu và biểu thức trình tạo được cho là ưu tiên trong nhiều trường hợp. Chúng dễ đọc hơn và được cho là nhanh hơn
Ví dụ 14
>>> (lambda a,b: a+b)(2,4) # apply the function immediately 6 >>> add = lambda a,b: a+b # assign the function to a variable >>> add(2,4) # execute the function 6 2Lưu ý rằng điều này không có nghĩa là chúng ta không thể sử dụng các hàm lambda trong các hàm bậc cao hơn, điều chúng tôi đang cố gắng chỉ ra là các biểu thức listcomp và trình tạo được ưu tiên trong nhiều trường hợp
Khi nào không sử dụng hàm Lambda
Các hàm lambda có những hạn chế và các phương pháp hay nhất. Trong phần này, chúng tôi sẽ trình bày chi tiết về một số
#1) Khi cần ràng buộc
Trong , nên sử dụng câu lệnh def thay vì gán hàm lambda cho một biến. Các hàm lambda được dùng trực tiếp và không được lưu để sử dụng sau này
Ví dụ 15
>>> (lambda a,b: a+b)(2,4) # apply the function immediately 6 >>> add = lambda a,b: a+b # assign the function to a variable >>> add(2,4) # execute the function 6 3Để thực thi hàm lambda ngay lập tức, chúng ta có thể sử dụng IIFE như đã thấy trong ví dụ 1 ở trên
#2) Khi Chú thích Loại được yêu cầu
Chúng tôi có thể muốn áp dụng các chú thích như trong các chức năng bình thường. Tuy nhiên, hàm lambda không hỗ trợ chú thích kiểu. Nếu nó được yêu cầu, thì tốt hơn hết chúng ta nên xác định các chức năng của mình bằng câu lệnh def
Ví dụ 16. Áp dụng chú thích loại trong hàm lambda.
>>> (lambda a,b: a+b)(2,4) # apply the function immediately 6 >>> add = lambda a,b: a+b # assign the function to a variable >>> add(2,4) # execute the function 6 4Như chúng ta có thể thấy ở trên, Lỗi Cú pháp sẽ xuất hiện nếu chúng ta cố gắng sử dụng chú thích kiểu trong hàm lambda
#3) Khi nào cần có Tuyên bố
Chúng ta đã thấy ở trên rằng hàm lambda không hỗ trợ câu lệnh. Cũng rất phổ biến, ví dụ , đưa ra các ngoại lệ trong một hàm bất cứ khi nào chúng ta xác định được vấn đề. Thật không may, hàm lambda không thể kết hợp câu lệnh tăng.
Nếu hàm của bạn cần hoạt động với các câu lệnh, thì hãy xác định nó bằng câu lệnh def thay vì câu lệnh lambda
Ví dụ 17. Tăng ngoại lệ trong hàm lambda.
>>> (lambda a,b: a+b)(2,4) # apply the function immediately 6 >>> add = lambda a,b: a+b # assign the function to a variable >>> add(2,4) # execute the function 6 5Các câu hỏi thường gặp
Câu hỏi 1) Các hàm Lambda có thể hỗ trợ chú thích loại không?
Câu trả lời. Rất tiếc, hàm lambda còn được gọi là hàm ẩn danh không hỗ trợ chú thích kiểu. Nếu cần chú thích kiểu, thì nên sử dụng câu lệnh def để xác định một hàm thông thường
Q #2) Lambda trả về loại nào trong Python?
Câu trả lời. Giống như các hàm thông thường, kiểu trả về của hàm lambda phụ thuộc vào những gì nó tính toán trong phần thân của nó. Nó có thể là int, float, cấu trúc dữ liệu (list, tuple, dictionary) và thậm chí là các hàm
Câu hỏi 3) Các hàm Lambda có hỗ trợ 'in' không?
Câu trả lời. Trong Python 2, các hàm lambda không hỗ trợ 'in' chỉ vì đó là một câu lệnh. Tuy nhiên, trong Python 3, chúng ta không còn câu lệnh in nữa mà là hàm in. Vì vậy, hàm lambda hỗ trợ rất nhiều cho 'print' trong Python 3
Phần kết luận
Trong hướng dẫn này, chúng ta đã xem xét các hàm lambda. Chúng tôi biết rằng chúng còn được gọi là hàm ẩn danh, biểu thức lambda, v.v.
Chúng tôi đã phân biệt hàm lambda với hàm thông thường của Python và cũng thấy sự giống nhau giữa chúng. Cuối cùng, chúng tôi đã kiểm tra các trường hợp khi nào và khi nào không sử dụng hàm lambda