Python và các ngôn ngữ khác như Java, C# và thậm chí C++ đã có các hàm lambda được thêm vào cú pháp của chúng, trong khi các ngôn ngữ như LISP hoặc họ ngôn ngữ ML, Haskell, OCaml và F#, sử dụng lambdas làm khái niệm cốt lõi Show
Lambda Python là các hàm nhỏ, ẩn danh, có cú pháp hạn chế hơn nhưng ngắn gọn hơn các hàm Python thông thường Đến cuối bài viết này, bạn sẽ biết
ghi chú. Bạn sẽ thấy một số ví dụ về mã sử dụng 2 dường như phớt lờ các phương pháp hay nhất về phong cách Python. Điều này chỉ nhằm mục đích minh họa các khái niệm tính toán lambda hoặc để làm nổi bật các khả năng của Python 2Những ví dụ đáng ngờ đó sẽ được đối chiếu với những cách tiếp cận hoặc giải pháp thay thế tốt hơn khi bạn tiến hành thông qua bài viết Hướng dẫn này chủ yếu dành cho các lập trình viên Python có trình độ từ trung cấp đến có kinh nghiệm, nhưng bất kỳ ai có đầu óc tò mò quan tâm đến lập trình và phép tính lambda đều có thể truy cập được. Tất cả các ví dụ trong hướng dẫn này đã được thử nghiệm với Python 3. 7 Lấy bài kiểm tra. Kiểm tra kiến thức của bạn với bài kiểm tra tương tác “Hàm Python Lambda” của chúng tôi. Sau khi hoàn thành, bạn sẽ nhận được điểm số để có thể theo dõi quá trình học tập của mình theo thời gian Lấy bài kiểm tra " Tải xuống miễn phí. Nhận một chương mẫu từ Thủ thuật Python. Cuốn sách chỉ cho bạn các phương pháp hay nhất về Python với các ví dụ đơn giản mà bạn có thể áp dụng ngay lập tức để viết mã Pythonic + đẹp hơn Phép tính LambdaCác biểu thức lambda trong Python và các ngôn ngữ lập trình khác có nguồn gốc từ phép tính lambda, một mô hình tính toán được phát minh bởi Alonzo Church. Bạn sẽ khám phá ra khi phép tính lambda được giới thiệu và tại sao nó là một khái niệm cơ bản lại xuất hiện trong hệ sinh thái Python Loại bỏ các quảng cáoMôn lịch sửNhà thờ Alonzo đã chính thức hóa phép tính lambda, một ngôn ngữ dựa trên sự trừu tượng thuần túy, vào những năm 1930. Các hàm lambda còn được gọi là trừu tượng lambda, một tham chiếu trực tiếp đến mô hình trừu tượng trong sáng tạo ban đầu của Alonzo Church Phép tính Lambda có thể mã hóa bất kỳ phép tính nào. Nó là Turing hoàn chỉnh, nhưng trái ngược với khái niệm về máy Turing, nó thuần túy và không giữ bất kỳ trạng thái nào Các ngôn ngữ hàm có nguồn gốc từ logic toán học và phép tính lambda, trong khi các ngôn ngữ lập trình mệnh lệnh sử dụng mô hình tính toán dựa trên trạng thái do Alan Turing phát minh. Hai mô hình tính toán, phép tính lambda và máy Turing, có thể dịch sang nhau. Sự tương đương này được gọi là giả thuyết Church-Turing Các ngôn ngữ hàm kế thừa trực tiếp triết lý tính toán lambda, áp dụng cách tiếp cận lập trình khai báo nhấn mạnh tính trừu tượng, chuyển đổi dữ liệu, thành phần và độ tinh khiết (không có trạng thái và không có tác dụng phụ). Ví dụ về các ngôn ngữ chức năng bao gồm Haskell, Lisp hoặc Erlang Ngược lại, Máy Turing dẫn đến lập trình mệnh lệnh được tìm thấy trong các ngôn ngữ như Fortran, C hoặc Python Phong cách mệnh lệnh bao gồm lập trình với các câu lệnh, điều khiển dòng chảy của chương trình từng bước với các hướng dẫn chi tiết. Cách tiếp cận này thúc đẩy đột biến và yêu cầu quản lý trạng thái Sự tách biệt trong cả hai họ thể hiện một số sắc thái, vì một số ngôn ngữ chức năng kết hợp các tính năng bắt buộc, như OCaml, trong khi các tính năng chức năng đã thấm vào họ ngôn ngữ bắt buộc, đặc biệt với việc giới thiệu các hàm lambda trong Java hoặc Python Python vốn dĩ không phải là một ngôn ngữ chức năng, nhưng nó đã sớm áp dụng một số khái niệm chức năng. Vào tháng 1 năm 1994, 4, 5, 6 và toán tử 2 đã được thêm vào ngôn ngữVí dụ đầu tiênDưới đây là một vài ví dụ để giúp bạn cảm thấy ngon miệng với một số mã Python, kiểu chức năng Hàm nhận dạng, một hàm trả về đối số của nó, được thể hiện bằng định nghĩa hàm Python tiêu chuẩn bằng cách sử dụng từ khóa 8 như sau>>>
9 lấy một đối số 0 và trả về nó khi được gọiNgược lại, nếu bạn sử dụng cấu trúc lambda Python, bạn sẽ nhận được thông tin sau >>> 0Trong ví dụ trên, biểu thức bao gồm
Ghi chú. Trong ngữ cảnh của bài viết này, một biến bị ràng buộc là một đối số cho hàm lambda Ngược lại, một biến tự do không bị ràng buộc và có thể được tham chiếu trong phần thân của biểu thức. Một biến miễn phí có thể là một hằng số hoặc một biến được xác định trong phạm vi kèm theo của hàm Bạn có thể viết một ví dụ phức tạp hơn một chút, một hàm thêm 4 vào một đối số, như sau>>> 5Bạn có thể áp dụng hàm ở trên cho một đối số bằng cách bao quanh hàm và đối số của nó bằng dấu ngoặc đơn >>> 6Giảm là một chiến lược tính toán lambda để tính giá trị của biểu thức. Trong ví dụ hiện tại, nó bao gồm việc thay thế biến ràng buộc 0 bằng đối số 6 9Vì hàm lambda là một biểu thức nên nó có thể được đặt tên. Do đó, bạn có thể viết mã trước đó như sau >>> 0Hàm lambda ở trên tương đương với việc viết cái này
Tất cả các chức năng này có một đối số duy nhất. Bạn có thể nhận thấy rằng, trong định nghĩa của lambdas, các đối số không có dấu ngoặc đơn xung quanh chúng. Các hàm đa đối số (các hàm nhận nhiều hơn một đối số) được thể hiện trong Python lambdas bằng cách liệt kê các đối số và phân tách chúng bằng dấu phẩy ( 7) nhưng không bao quanh chúng bằng dấu ngoặc đơn>>>
Hàm lambda được gán cho 8 nhận hai đối số và trả về một chuỗi nội suy hai tham số 9 và 60. Như mong đợi, định nghĩa của lambda liệt kê các đối số không có dấu ngoặc đơn, trong khi việc gọi hàm được thực hiện chính xác như một hàm Python bình thường, với các dấu ngoặc đơn bao quanh các đối sốLoại bỏ các quảng cáoHàm ẩn danhCác thuật ngữ sau đây có thể được sử dụng thay thế cho nhau tùy thuộc vào loại ngôn ngữ lập trình và văn hóa
Đối với phần còn lại của bài viết này sau phần này, hầu như bạn sẽ thấy thuật ngữ hàm lambda Theo nghĩa đen, 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 2. Nói một cách lỏng lẻo hơn, nó có thể được đặt tên hoặc không. Xem xét hàm ẩn danh hai đối số được xác định bằng 2 nhưng không bị ràng buộc với một biến. Lambda không được đặt tên>>> 6Hàm trên định nghĩa một biểu thức lambda nhận hai đối số và trả về tổng của chúng Ngoài việc cung cấp cho bạn thông tin phản hồi rằng Python hoàn toàn ổn với biểu mẫu này, nó không dẫn đến bất kỳ ứng dụng thực tế nào. Bạn có thể gọi hàm trong trình thông dịch Python >>> 0Ví dụ trên đang tận dụng tính năng tương tác chỉ dành cho trình thông dịch được cung cấp thông qua dấu gạch dưới ( 63). Xem ghi chú bên dưới để biết thêm chi tiếtBạn không thể viết mã tương tự trong mô-đun Python. Hãy coi 63 trong trình thông dịch là tác dụng phụ mà bạn đã lợi dụng. Trong một mô-đun Python, bạn sẽ gán tên cho lambda hoặc bạn sẽ chuyển lambda cho một hàm. Bạn sẽ sử dụng hai cách tiếp cận đó sau trong bài viết nàyGhi chú. Trong trình thông dịch tương tác, dấu gạch dưới đơn ( 63) được liên kết với biểu thức cuối cùng được đánh giáTrong ví dụ trên, 63 trỏ đến hàm lambda. Để biết thêm chi tiết về cách sử dụng ký tự đặc biệt này trong Python, hãy xem Ý nghĩa của dấu gạch dưới trong PythonMột mẫu khác được sử dụng trong các ngôn ngữ khác như JavaScript là thực thi ngay hàm lambda Python. Đây được gọi là Biểu thức hàm được gọi ngay lập tức (IIFE, phát âm là “iffy”). Đây là một ví dụ >>> 00Hàm lambda ở trên được xác định và sau đó được gọi ngay với hai đối số ( 6 và 68). Nó trả về giá trị 69, là tổng của các đối sốMột số ví dụ trong hướng dẫn này sử dụng định dạng này để làm nổi bật khía cạnh ẩn danh của hàm lambda và tránh tập trung vào 2 trong Python như một cách ngắn gọn hơn để xác định hàmPython không khuyến khích sử dụng các biểu thức lambda được gọi ngay lập tức. Nó chỉ đơn giản là kết quả của một biểu thức lambda có thể gọi được, không giống như phần thân của một hàm bình thường Các hàm lambda thường được sử dụng với các hàm bậc cao hơn, lấy một hoặc nhiều hàm làm đối số hoặc trả về một hoặc nhiều hàm Hàm lambda có thể là hàm bậc cao hơn bằng cách lấy một hàm (bình thường hoặc lambda) làm đối số như trong ví dụ giả định sau >>> 01Python hiển thị các hàm bậc cao hơn dưới dạng các hàm tích hợp sẵn hoặc trong thư viện chuẩn. Các ví dụ bao gồm 4, 5, 03, cũng như các chức năng chính như ________ 304, ________ 305, ________ 306 và ________ 307. Bạn sẽ sử dụng các hàm lambda cùng với các hàm bậc cao hơn của Python trong phần Sử dụng biểu thức Lambda phù hợpLoại bỏ các quảng cáoPython Lambda và các hàm thông thườngTrích dẫn này từ Câu hỏi thường gặp về Lịch sử và Thiết kế Python dường như đặt ra âm thanh về kỳ vọng chung liên quan đến việc sử dụng các hàm lambda trong Python
Tuy nhiên, đừng để tuyên bố này ngăn cản bạn sử dụng 2 của Python. Thoạt nhìn, bạn có thể chấp nhận rằng hàm lambda là một hàm có một số đường cú pháp rút ngắn mã để xác định hoặc gọi một hàm. Các phần sau đây nêu bật những điểm tương đồng và khác biệt tinh tế giữa các hàm Python bình thường và hàm lambdaChức năngTại thời điểm này, bạn có thể thắc mắc về cơ bản điều gì phân biệt một hàm lambda được liên kết với một biến với một hàm thông thường có một dòng 09. dưới bề mặt, hầu như không có gì. Hãy xác minh cách Python nhìn thấy một hàm được xây dựng bằng một câu lệnh return duy nhất so với một hàm được xây dựng dưới dạng một biểu thức ( 2)Mô-đun 001 hiển thị các hàm để phân tích mã byte Python do trình biên dịch Python tạo ra>>> 02Bạn có thể thấy rằng 002 hiển thị một phiên bản có thể đọc được của mã byte Python cho phép kiểm tra các hướng dẫn cấp thấp mà trình thông dịch Python sẽ sử dụng trong khi thực thi chương trìnhBây giờ hãy xem nó với một đối tượng chức năng thông thường >>> 03Mã byte được giải thích bởi Python giống nhau cho cả hai chức năng. Nhưng bạn có thể nhận thấy rằng cách đặt tên khác. tên hàm là 003 cho một hàm được xác định bằng 8, trong khi hàm lambda Python được xem là 2Tìm lạiBạn đã thấy trong phần trước rằng, trong ngữ cảnh của hàm lambda, Python không cung cấp tên của hàm, mà chỉ cung cấp tên của hàm là 006. Đây có thể là một hạn chế cần xem xét khi xảy ra ngoại lệ và truy nguyên chỉ hiển thị 006>>> 04Truy nguyên của một ngoại lệ được đưa ra trong khi hàm lambda được thực thi chỉ xác định hàm gây ra ngoại lệ là 006Đây là ngoại lệ tương tự được đưa ra bởi một chức năng bình thường >>> 05Hàm bình thường gây ra lỗi tương tự nhưng dẫn đến truy nguyên chính xác hơn vì nó cung cấp tên hàm, 009cú phápNhư bạn đã thấy trong các phần trước, biểu mẫu lambda thể hiện sự khác biệt về cú pháp với một hàm thông thường. Cụ thể, một hàm lambda có các đặc điểm sau
không có báo cáo Hàm lambda không được chứa bất kỳ câu lệnh nào. Trong một hàm lambda, các câu lệnh như 09, 011, 012 hoặc 013 sẽ đưa ra một ngoại lệ 014. Đây là một ví dụ về việc thêm 012 vào phần thân của lambda>>> 06Ví dụ giả định này nhằm 012 rằng tham số 0 có giá trị là 6. Tuy nhiên, trình thông dịch xác định một 014 trong khi phân tích cú pháp mã liên quan đến câu lệnh 012 trong phần thân của 2Biểu thức đơn Ngược lại với một hàm thông thường, hàm lambda trong Python là một biểu thức đơn. Mặc dù, trong phần thân của 2, bạn có thể trải rộng biểu thức trên nhiều dòng bằng cách sử dụng dấu ngoặc đơn hoặc chuỗi nhiều dòng, nó vẫn là một biểu thức duy nhất>>> 07Ví dụ trên trả về chuỗi 023 khi đối số lambda là số lẻ và 024 khi đối số là số chẵn. Nó trải rộng trên hai dòng bởi vì nó được chứa trong một tập hợp các dấu ngoặc đơn, nhưng nó vẫn là một biểu thức duy nhấtLoại chú thích Nếu bạn đã bắt đầu áp dụng gợi ý kiểu, hiện đã có trong Python, thì bạn có một lý do chính đáng khác để thích các hàm thông thường hơn các hàm lambda của Python. Xem Kiểm tra loại Python (Hướng dẫn) để tìm hiểu thêm về gợi ý loại Python và kiểm tra loại. Trong một hàm lambda, không có tương đương với những điều sau đây 08Bất kỳ lỗi loại nào với 025 đều có thể được phát hiện bằng các công cụ như 026 hoặc 027, trong khi một 014 có hàm lambda tương đương được đưa ra trong thời gian chạy>>> 09Giống như cố gắng đưa một câu lệnh vào lambda, việc thêm chú thích loại ngay lập tức dẫn đến một 014 khi chạyIIFE Bạn đã thấy một số ví dụ về thực thi chức năng được gọi ngay lập tức >>> 50Ngoài trình thông dịch Python, tính năng này có lẽ không được sử dụng trong thực tế. Đó là hệ quả trực tiếp của hàm lambda có thể gọi được khi nó được định nghĩa. Ví dụ: điều này cho phép bạn chuyển định nghĩa của biểu thức lambda Python sang một hàm bậc cao hơn như 4, 5 hoặc 03 hoặc một hàm chínhLoại bỏ các quảng cáoTranh luậnGiống như một đối tượng hàm bình thường được định nghĩa bằng 8, các biểu thức lambda Python hỗ trợ tất cả các cách truyền đối số khác nhau. Điêu nay bao gôm
Các ví dụ sau minh họa các tùy chọn mở cho bạn để chuyển đối số cho biểu thức lambda >>> 51người trang tríTrong Python, một trình trang trí là việc triển khai một mẫu cho phép thêm một hành vi vào một hàm hoặc một lớp. Nó thường được thể hiện bằng cú pháp 034 tiền tố một hàm. Đây là một ví dụ giả tạo 52Trong ví dụ trên, 035 là một hàm thêm một hành vi vào 036, để việc gọi 037 dẫn đến đầu ra sau 53 036 chỉ in 039, nhưng trình trang trí thêm một hành vi bổ sung cũng in 040Một trình trang trí có thể được áp dụng cho lambda. Mặc dù không thể trang trí lambda bằng cú pháp 034, nhưng trình trang trí chỉ là một hàm, vì vậy nó có thể gọi hàm lambda 54 042, được trang trí bằng 043 trên dòng 11, được gọi với đối số 68 trên dòng 15. Ngược lại, ở dòng 18, một hàm lambda ngay lập tức được nhúng vào một lệnh gọi tới 045, trình trang trí. Khi bạn thực thi đoạn mã trên, bạn sẽ nhận được thông tin sau 55Xem cách, như bạn đã thấy, tên của hàm lambda xuất hiện dưới dạng 006, trong khi 047 được xác định rõ ràng cho hàm thông thườngTrang trí hàm lambda theo cách này có thể hữu ích cho mục đích gỡ lỗi, có thể để gỡ lỗi hành vi của hàm lambda được sử dụng trong ngữ cảnh của hàm bậc cao hơn hoặc hàm chính. Hãy xem một ví dụ với 4 56Đối số đầu tiên của 4 là một lambda nhân đối số của nó với 6. Lambda này được trang trí bằng 045. Khi được thực thi, ví dụ trên xuất ra kết quả như sau 57Kết quả 052 là danh sách có được khi nhân từng phần tử của 053. Hiện tại, coi 053 tương đương với danh sách 055Bạn sẽ được tiếp xúc với 4 chi tiết hơn trong Bản đồLambda cũng có thể là một công cụ trang trí, nhưng nó không được khuyến khích. Nếu bạn thấy mình cần làm điều này, hãy tham khảo PEP 8, Đề xuất lập trình Để biết thêm về trình trang trí Python, hãy xem Primer on Python Decorators Loại bỏ các quảng cáoKhép kínBao đóng là một hàm trong đó mọi biến tự do, mọi thứ trừ tham số, được sử dụng trong hàm đó được liên kết với một giá trị cụ thể được xác định trong phạm vi kèm theo của hàm đó. Trên thực tế, các bao đóng xác định môi trường mà chúng chạy và do đó có thể được gọi từ bất kỳ đâu Các khái niệm về lambda và bao đóng không nhất thiết phải liên quan với nhau, mặc dù các hàm lambda có thể đóng theo cách giống như các hàm thông thường cũng có thể đóng. Một số ngôn ngữ có cấu trúc đặc biệt để đóng hoặc lambda (ví dụ: Groovy với một khối mã ẩn danh làm đối tượng Đóng) hoặc biểu thức lambda (ví dụ: biểu thức Java Lambda với tùy chọn giới hạn để đóng) Đây là một bao đóng được xây dựng bằng hàm Python bình thường 58 057 trả về 058, một hàm lồng nhau tính tổng của ba đối số
Để kiểm tra hành vi của 057 và 058, 057 được gọi ba lần trong vòng lặp 068 in ra thông tin sau 59Trên dòng 9 của mã, 058 được trả về bởi lời gọi của 057 bị ràng buộc với tên 071. Ở dòng 5, 058 nắm bắt 0 và 061 vì nó có quyền truy cập vào môi trường nhúng của nó, sao cho khi gọi hàm đóng, nó có thể hoạt động trên hai biến tự do 0 và 061Tương tự, một 2 cũng có thể là một bao đóng. Đây là ví dụ tương tự với hàm lambda Python 60Khi bạn thực thi đoạn mã trên, bạn nhận được đầu ra sau 61Ở dòng 6, 057 trả về một lambda và gán nó cho biến 071. Ở dòng 3, phần thân của hàm lambda tham chiếu đến 0 và 061. Biến 061 có sẵn tại thời điểm định nghĩa, trong khi đó, 0 được xác định tại thời điểm chạy khi 057 được gọiTrong tình huống này, cả chức năng bình thường và lambda đều hoạt động giống nhau. Trong phần tiếp theo, bạn sẽ thấy tình huống trong đó hành vi của lambda có thể bị đánh lừa do thời gian đánh giá của nó (thời gian xác định so với thời gian chạy) Thời gian đánh giáTrong một số tình huống liên quan đến vòng lặp, hành vi của hàm lambda Python dưới dạng bao đóng có thể phản trực giác. Nó đòi hỏi sự hiểu biết khi các biến miễn phí bị ràng buộc trong ngữ cảnh của lambda. Các ví dụ sau minh họa sự khác biệt khi sử dụng hàm thông thường so với sử dụng Python lambda Kiểm tra kịch bản trước bằng cách sử dụng chức năng thông thường >>> 62Trong một chức năng bình thường, 085 được đánh giá tại thời điểm định nghĩa, trên dòng 9, khi chức năng được thêm vào danh sách. 086Bây giờ, với việc triển khai logic tương tự với hàm lambda, hãy quan sát hành vi không mong muốn >>> 63Kết quả không mong muốn xảy ra vì biến miễn phí 085, khi được triển khai, bị ràng buộc tại thời điểm thực hiện biểu thức lambda. Hàm lambda của Python trên dòng 4 là một bao đóng bắt giữ 085, một biến tự do bị ràng buộc trong thời gian chạy. Khi chạy, trong khi gọi hàm 089 trên dòng 7, giá trị của 085 là 091Để khắc phục vấn đề này, bạn có thể gán biến tự do tại thời điểm định nghĩa như sau >>> 64Một hàm lambda Python hoạt động giống như một hàm bình thường đối với các đối số. Do đó, một tham số lambda có thể được khởi tạo với giá trị mặc định. tham số 085 lấy bên ngoài 085 làm giá trị mặc định. Hàm lambda Python có thể đã được viết là 094 và có kết quả tương tựHàm lambda Python được gọi mà không có bất kỳ đối số nào trên dòng 7 và nó sử dụng giá trị mặc định 085 được đặt tại thời điểm định nghĩaLoại bỏ các quảng cáoKiểm tra LambdaLambdas Python có thể được kiểm tra tương tự như các chức năng thông thường. Có thể sử dụng cả 096 và 097 096Mô-đun 096 xử lý các hàm lambda Python tương tự như các hàm thông thường 65 500 định nghĩa một trường hợp thử nghiệm với ba phương thức thử nghiệm, mỗi phương thức thực hiện một kịch bản thử nghiệm cho 501 được triển khai dưới dạng hàm lambda. Việc thực thi tệp Python 502 chứa 500 tạo ra như sau 66Như mong đợi, chúng tôi có hai trường hợp thử nghiệm thành công và một trường hợp thất bại cho 504. kết quả là 69, nhưng kết quả mong đợi là 506. Thất bại này là do lỗi cố ý trong trường hợp thử nghiệm. Thay đổi kết quả dự kiến từ 506 thành 69 sẽ đáp ứng tất cả các bài kiểm tra cho 500 097Mô-đun 097 trích xuất mã Python tương tác từ 512 để thực hiện kiểm tra. Mặc dù cú pháp của các hàm lambda Python không hỗ trợ một 512 điển hình, nhưng có thể gán một chuỗi cho phần tử 514 của một lambda có tên 67 097 trong doc comment của lambda 501 mô tả các trường hợp thử nghiệm giống như trong phần trướcKhi bạn thực hiện các bài kiểm tra qua 517, bạn sẽ nhận được thông tin sau 68Kết quả kiểm tra thất bại từ lỗi tương tự được giải thích trong quá trình thực hiện kiểm tra đơn vị trong phần trước Bạn có thể thêm một 512 vào một lambda Python thông qua một phép gán cho 514 để ghi lại một hàm lambda. Mặc dù có thể, nhưng cú pháp Python phù hợp hơn với 512 cho các hàm thông thường so với các hàm lambdaĐể biết tổng quan toàn diện về thử nghiệm đơn vị trong Python, bạn có thể tham khảo Bắt đầu với thử nghiệm trong Python Lạm dụng biểu hiện LambdaMột số ví dụ trong bài viết này, nếu được viết trong ngữ cảnh mã Python chuyên nghiệp, sẽ bị coi là lạm dụng Nếu bạn thấy mình đang cố khắc phục điều gì đó mà biểu thức lambda không hỗ trợ, đây có thể là dấu hiệu cho thấy một chức năng bình thường sẽ phù hợp hơn. 512 cho biểu thức lambda trong phần trước là một ví dụ điển hình. Cố gắng khắc phục thực tế là hàm lambda Python không hỗ trợ các câu lệnh là một dấu hiệu đỏ khácCác phần tiếp theo minh họa một số ví dụ về cách sử dụng lambda nên tránh. Những ví dụ đó có thể là những tình huống trong ngữ cảnh của Python lambda, mã hiển thị mẫu sau
Tăng một ngoại lệCố gắng đưa ra một ngoại lệ trong Python lambda sẽ khiến bạn phải suy nghĩ kỹ. Có một số cách thông minh để làm như vậy, nhưng ngay cả những cách như sau vẫn tốt hơn để tránh >>> 69Vì một câu lệnh không đúng về mặt cú pháp trong phần thân lambda của Python, nên cách giải quyết trong ví dụ trên bao gồm trừu tượng hóa lệnh gọi câu lệnh bằng một hàm chuyên dụng 522. Nên tránh sử dụng loại giải pháp thay thế này. Nếu bạn gặp loại mã này, bạn nên xem xét cấu trúc lại mã để sử dụng một chức năng thông thườngPhong cách mật mãNhư trong bất kỳ ngôn ngữ lập trình nào, bạn sẽ thấy mã Python khó đọc do phong cách được sử dụng. Các hàm lambda, do tính ngắn gọn của chúng, có thể thuận lợi cho việc viết mã khó đọc Ví dụ lambda sau đây chứa một số lựa chọn kiểu xấu >>> 90Dấu gạch dưới ( 63) đề cập đến một biến mà bạn không cần phải đề cập đến một cách rõ ràng. Nhưng trong ví dụ này, ba 63 đề cập đến các biến khác nhau. Nâng cấp ban đầu cho mã lambda này có thể là đặt tên cho các biến>>> 91Phải thừa nhận rằng nó vẫn còn khó đọc. Bằng cách vẫn tận dụng một 2, một chức năng thông thường sẽ đi một chặng đường dài để làm cho mã này dễ đọc hơn, trải rộng logic trên một vài dòng và lệnh gọi hàm>>> 92Điều này vẫn chưa tối ưu nhưng cho bạn thấy một đường dẫn khả thi để tạo mã và đặc biệt là các hàm lambda của Python, dễ đọc hơn. Trong Các lựa chọn thay thế cho Lambdas, bạn sẽ học cách thay thế 4 và 2 bằng cách hiểu danh sách hoặc biểu thức trình tạo. Điều này sẽ cải thiện đáng kể khả năng đọc mãLớp học PythonBạn có thể nhưng không nên viết các phương thức lớp dưới dạng các hàm lambda Python. Ví dụ sau đây là mã Python hoàn toàn hợp pháp nhưng thể hiện mã Python độc đáo dựa trên 2. Ví dụ: thay vì triển khai 529 như một chức năng thông thường, nó sử dụng một 2. Tương tự, 531 và 532 là các thuộc tính cũng được triển khai với các hàm lambda, thay vì các hàm hoặc trình trang trí thông thường 93Chạy một công cụ như 533, một công cụ thực thi hướng dẫn kiểu, sẽ hiển thị các lỗi sau cho 529 và 535 94Mặc dù 533 không chỉ ra vấn đề đối với việc sử dụng các hàm lambda Python trong các thuộc tính, nhưng chúng rất khó đọc và dễ bị lỗi do sử dụng nhiều chuỗi như 537 và 538Việc thực hiện đúng 529 sẽ được mong đợi như sau 95 531 sẽ được viết như sau 96Theo nguyên tắc chung, trong ngữ cảnh mã được viết bằng Python, hãy ưu tiên các hàm thông thường hơn biểu thức lambda. Tuy nhiên, có những trường hợp được hưởng lợi từ cú pháp lambda, như bạn sẽ thấy trong phần tiếp theo Loại bỏ các quảng cáoSử dụng thích hợp các biểu thức LambdaLambdas trong Python có xu hướng trở thành chủ đề gây tranh cãi. Một số đối số chống lại lambdas trong Python là
Bất chấp các cuộc tranh luận sôi nổi đặt câu hỏi về sự tồn tại đơn thuần của tính năng này trong Python, các hàm lambda có các thuộc tính đôi khi cung cấp giá trị cho ngôn ngữ Python và cho các nhà phát triển Các ví dụ sau minh họa các tình huống trong đó việc sử dụng các hàm lambda không chỉ phù hợp mà còn được khuyến khích trong mã Python Cấu trúc chức năng cổ điểnCác hàm lambda thường được sử dụng với các hàm tích hợp sẵn 4 và 5, cũng như 03, được cung cấp trong mô-đun 545. Ba ví dụ sau đây là minh họa tương ứng về việc sử dụng các hàm đó với các biểu thức lambda làm bạn đồng hành>>> 97Bạn có thể phải đọc mã giống như các ví dụ trên, mặc dù có nhiều dữ liệu phù hợp hơn. Vì lý do đó, điều quan trọng là phải nhận ra những cấu trúc đó. Tuy nhiên, những cấu trúc đó có các lựa chọn thay thế tương đương được coi là Pythonic hơn. Trong Các lựa chọn thay thế cho Lambda, bạn sẽ tìm hiểu cách chuyển đổi các hàm bậc cao hơn và các lambda đi kèm của chúng thành các dạng thành ngữ khác Chức năng chínhCác hàm chính trong Python là các hàm bậc cao lấy tham số 546 làm đối số được đặt tên. 546 nhận một chức năng có thể là một 2. Chức năng này ảnh hưởng trực tiếp đến thuật toán do chính chức năng chính điều khiển. Dưới đây là một số chức năng chính
Hãy tưởng tượng rằng bạn muốn sắp xếp danh sách ID được biểu thị dưới dạng chuỗi. Mỗi ID là phần nối của chuỗi 556 và một số. Sắp xếp danh sách này bằng hàm tích hợp sẵn 05, theo mặc định, sử dụng thứ tự từ điển vì các phần tử trong danh sách là các chuỗiĐể tác động đến việc thực thi sắp xếp, bạn có thể gán lambda cho đối số có tên là 546, sao cho việc sắp xếp sẽ sử dụng số được liên kết với ID>>> 98Khung giao diện người dùngCác khung giao diện người dùng như Tkinter, wxPython hoặc. NET Windows Forms với IronPython tận dụng các chức năng lambda để ánh xạ các hành động để đáp ứng với các sự kiện giao diện người dùng Chương trình Tkinter ngây thơ dưới đây minh họa cách sử dụng 2 được gán cho lệnh của nút Đảo ngược 99Nhấp vào nút Đảo ngược kích hoạt một sự kiện kích hoạt hàm lambda, thay đổi nhãn từ Lambda Calculus thành suluclaC adbmaL* Cả wxPython và IronPython trên. NET chia sẻ một cách tiếp cận tương tự để xử lý các sự kiện. Lưu ý rằng 2 là một cách để xử lý các sự kiện kích hoạt, nhưng một chức năng có thể được sử dụng cho cùng một mục đích. Cuối cùng, nó trở nên khép kín và ít dài dòng hơn khi sử dụng 2 khi lượng mã cần thiết rất ngắnĐể khám phá wxPython, hãy xem Cách xây dựng ứng dụng GUI Python với wxPython Loại bỏ các quảng cáoTrình thông dịch PythonKhi bạn đang chơi với mã Python trong trình thông dịch tương tác, các hàm lambda của Python thường là một điều may mắn. Thật dễ dàng để tạo một chức năng một lớp lót nhanh chóng để khám phá một số đoạn mã sẽ không bao giờ nhìn thấy ánh sáng ban ngày bên ngoài trình thông dịch. Lambdas được viết trong trình thông dịch, để khám phá nhanh chóng, giống như giấy vụn mà bạn có thể vứt đi sau khi sử dụng def add_one(x): return x + 1 562Theo tinh thần giống như thử nghiệm trong trình thông dịch Python, mô-đun 562 cung cấp các hàm tính thời gian cho các đoạn mã nhỏ. 564 nói riêng có thể được gọi trực tiếp, chuyển một số mã Python trong một chuỗi. Đây là một ví dụ>>> 00Khi câu lệnh được truyền dưới dạng chuỗi, 565 cần có ngữ cảnh đầy đủ. Trong ví dụ trên, điều này được cung cấp bởi đối số thứ hai thiết lập môi trường cần thiết cho chức năng chính được tính thời gian. Không làm như vậy sẽ gây ra một ngoại lệ 566Một cách tiếp cận khác là sử dụng một 2>>> 01Giải pháp này sạch hơn, dễ đọc hơn và nhập trình thông dịch nhanh hơn. Mặc dù thời gian thực hiện ít hơn một chút đối với phiên bản 2, nhưng việc thực hiện lại các chức năng có thể cho thấy một chút lợi thế đối với phiên bản 569. Thời gian thực hiện của 570 được loại trừ khỏi thời gian thực hiện tổng thể và không có bất kỳ tác động nào đến kết quảkhỉ váĐể thử nghiệm, đôi khi cần phải dựa vào các kết quả có thể lặp lại, ngay cả khi trong quá trình thực thi bình thường của một phần mềm nhất định, các kết quả tương ứng dự kiến sẽ khác nhau hoặc thậm chí là hoàn toàn ngẫu nhiên Giả sử bạn muốn kiểm tra một chức năng, trong thời gian chạy, xử lý các giá trị ngẫu nhiên. Tuy nhiên, trong quá trình thực hiện thử nghiệm, bạn cần xác nhận các giá trị có thể dự đoán theo cách có thể lặp lại. Ví dụ sau đây cho thấy cách, với hàm 2, bản vá khỉ có thể giúp bạn 02Trình quản lý ngữ cảnh giúp cách ly hoạt động của khỉ vá một hàm từ thư viện chuẩn ( 572, trong ví dụ này). Hàm lambda được gán cho 573 thay thế hành vi mặc định bằng cách trả về một giá trị tĩnhĐiều này cho phép kiểm tra bất kỳ chức năng nào tùy thuộc vào 574 theo cách có thể dự đoán được. Trước khi thoát khỏi trình quản lý bối cảnh, hành vi mặc định của 574 được thiết lập lại để loại bỏ bất kỳ tác dụng phụ không mong muốn nào có thể ảnh hưởng đến các khu vực khác của thử nghiệm có thể phụ thuộc vào hành vi mặc định của 574Các khung kiểm tra đơn vị như 096 và 578 đưa khái niệm này lên một mức độ phức tạp cao hơnVới 578, vẫn sử dụng hàm 2, ví dụ tương tự trở nên thanh lịch và ngắn gọn hơn 03Với vật cố định pytest 581, 573 được ghi đè bằng lambda sẽ trả về một giá trị xác định, 583, cho phép xác thực thử nghiệm. Vật cố định pytest 581 cho phép bạn kiểm soát phạm vi ghi đè. Trong ví dụ trên, việc gọi 573 trong các thử nghiệm tiếp theo, mà không sử dụng bản vá khỉ, sẽ thực thi chức năng này bình thườngThực hiện kiểm tra 578 cho kết quả sau 04Bài kiểm tra vượt qua khi chúng tôi xác nhận rằng 587 đã được thực hiện và kết quả là kết quả mong đợi trong bối cảnh bài kiểm traLoại bỏ các quảng cáoCác lựa chọn thay thế cho LambdaMặc dù có những lý do tuyệt vời để sử dụng 2, nhưng vẫn có những trường hợp việc sử dụng nó bị phản đối. Vì vậy, các lựa chọn thay thế là gì?Các hàm bậc cao hơn như 4, 5 và 03 có thể được chuyển đổi thành các dạng thanh lịch hơn với một chút sáng tạo, đặc biệt là với khả năng hiểu danh sách hoặc biểu thức trình tạoĐể tìm hiểu thêm về cách hiểu danh sách, hãy xem Khi nào nên sử dụng cách hiểu danh sách trong Python. Để tìm hiểu thêm về các biểu thức trình tạo, hãy xem Cách sử dụng Trình tạo và năng suất trong Python Bản đồHàm tích hợp sẵn 4 lấy một hàm làm đối số đầu tiên và áp dụng nó cho từng thành phần của đối số thứ hai, một hàm có thể lặp lại. Ví dụ về iterables là chuỗi, danh sách và bộ dữ liệu. Để biết thêm thông tin về iterables và iterators, hãy xem Iterables và Iterators 4 trả về một iterator tương ứng với bộ sưu tập được chuyển đổi. Ví dụ: nếu bạn muốn chuyển đổi danh sách chuỗi thành danh sách mới với mỗi chuỗi được viết hoa, bạn có thể sử dụng 4, như sau>>> 05Bạn cần gọi 595 để chuyển đổi trình vòng lặp được trả về bởi 4 thành một danh sách mở rộng có thể được hiển thị trong trình thông dịch trình bao PythonSử dụng khả năng hiểu danh sách giúp loại bỏ nhu cầu xác định và gọi hàm lambda >>> 06LọcHàm tích hợp sẵn 5, một cấu trúc hàm cổ điển khác, có thể được chuyển đổi thành cách hiểu danh sách. Nó lấy một biến vị ngữ làm đối số đầu tiên và một biến lặp lại làm đối số thứ hai. Nó xây dựng một iterator chứa tất cả các phần tử của tập hợp ban đầu thỏa mãn chức năng vị ngữ. Đây là một ví dụ lọc tất cả các số chẵn trong một danh sách các số nguyên đã cho>>> 07Lưu ý rằng 5 trả về một trình vòng lặp, do đó cần gọi loại tích hợp sẵn 599 để xây dựng một danh sách được cung cấp một trình vòng lặpViệc triển khai tận dụng cấu trúc hiểu danh sách đưa ra những điều sau đây >>> 08GiảmKể từ Python 3, 6 đã chuyển từ chức năng tích hợp sang chức năng mô-đun 545. Là 4 và 5, hai đối số đầu tiên của nó lần lượt là một hàm và một hàm lặp. Nó cũng có thể lấy một bộ khởi tạo làm đối số thứ ba được sử dụng làm giá trị ban đầu của bộ tích lũy kết quả. Đối với mỗi phần tử của iterable, 6 áp dụng hàm và tích lũy kết quả được trả về khi iterable cạn kiệtĐể áp dụng 6 cho một danh sách các cặp và tính tổng của phần tử đầu tiên của mỗi cặp, bạn có thể viết>>> 09Một cách tiếp cận thành ngữ hơn bằng cách sử dụng biểu thức trình tạo, làm đối số cho 606 trong ví dụ, như sau>>> 0Một giải pháp hơi khác và có thể sạch hơn sẽ loại bỏ nhu cầu truy cập rõ ràng vào phần tử đầu tiên của cặp và thay vào đó sử dụng giải nén >>> 1Việc sử dụng dấu gạch dưới ( 63) là một quy ước Python chỉ ra rằng bạn có thể bỏ qua giá trị thứ hai của cặp 606 lấy một đối số duy nhất, vì vậy biểu thức trình tạo không cần phải nằm trong dấu ngoặc đơnLambdas có phải Pythonic hay không?PEP 8, là hướng dẫn phong cách cho mã Python, đọc
Điều này hoàn toàn không khuyến khích sử dụng lambda được liên kết với một mã định danh, chủ yếu là nơi các chức năng nên được sử dụng và có nhiều lợi ích hơn. PEP 8 không đề cập đến các cách sử dụng khác của 2. Như bạn đã thấy trong các phần trước, các hàm lambda chắc chắn có thể có những công dụng tốt, mặc dù chúng bị hạn chế.Một cách có thể để trả lời câu hỏi là các hàm lambda hoàn toàn là Pythonic nếu không có gì Pythonic khả dụng hơn. Tôi đang tránh xa việc định nghĩa “Pythonic” nghĩa là gì, để lại cho bạn định nghĩa phù hợp nhất với suy nghĩ của bạn, cũng như phong cách viết mã của cá nhân bạn hoặc nhóm của bạn Ngoài phạm vi hẹp của Python 2, Cách viết mã Python đẹp bằng PEP 8 là một tài nguyên tuyệt vời mà bạn có thể muốn xem về kiểu mã trong PythonPhần kết luậnBây giờ bạn đã biết cách sử dụng các hàm 2 của Python và có thể
Nếu bạn có thiên hướng về toán học, bạn có thể có một số niềm vui khi khám phá thế giới hấp dẫn của phép tính lambda Python lambdas giống như muối. Một nhúm nhỏ trong thư rác, giăm bông và trứng của bạn sẽ làm tăng hương vị, nhưng quá nhiều sẽ làm hỏng món ăn Lấy bài kiểm tra. Kiểm tra kiến thức của bạn với bài kiểm tra tương tác “Hàm Python Lambda” của chúng tôi. Sau khi hoàn thành, bạn sẽ nhận được điểm số để có thể theo dõi quá trình học tập của mình theo thời gian Lấy bài kiểm tra " Ghi chú. Ngôn ngữ lập trình Python, được đặt tên theo Monty Python, thích sử dụng 612, 613 và 614 làm biến siêu cú pháp, thay vì truyền thống 615, 616 và 617Đánh dấu là đã hoàn thành Xem ngay Hướng dẫn này có một khóa học video liên quan do nhóm Real Python tạo. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn. Cách sử dụng các hàm Lambda của Python 🐍 Thủ thuật Python 💌 Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python Gửi cho tôi thủ thuật Python » Giới thiệu về André Burgaud Andre là một kỹ sư phần mềm dày dặn đam mê công nghệ và ngôn ngữ lập trình, đặc biệt là Python » Thông tin thêm về AndréMỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là Aldren Jon Joanna Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia Nâng cao kỹ năng Python của bạn » Bậc thầy Kỹ năng Python trong thế giới thực Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia Nâng cao kỹ năng Python của bạn » Bạn nghĩ sao? Đánh giá bài viết này Tweet Chia sẻ Chia sẻ EmailBài học số 1 hoặc điều yêu thích mà bạn đã học được là gì? Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. Nhận các mẹo để đặt câu hỏi hay và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi |