Hướng dẫn python pass lambda as argument - python vượt qua lambda làm đối số
Hàm Lambda (hay chính xác hơn là biểu thức Lambda) chỉ đơn giản là một hàm bạn có thể xác định tại chỗ, ngay tại nơi bạn cần. Ví dụ, Show
hoàn toàn giống như
Và khi tôi nói chính xác, ý tôi là nó - họ tháo rời với cùng một mã byte. Sự khác biệt duy nhất giữa hai là cái được xác định trong ví dụ thứ hai có tên. Biểu thức lambda trở nên hữu ích vì việc tạo ra một biểu thức không phải là một tuyên bố, điều đó có nghĩa là, như những người khác đã trả lời, bạn có thể làm
để có được chính xác những gì bạn muốn. Tuy nhiên, sự khác biệt chính giữa các biểu thức Lambda và các hàm chính quy là Lambdas bị hạn chế hơn. Lambdas chỉ có thể chứa các biểu thức, không phải câu lệnh. Một biểu thức là bất cứ điều gì bạn có thể đặt ở phía bên phải của bài tập 2. .Điều này có nghĩa là một biểu thức lambda không thể gán cho một biến (trên thực tế, nó không thể có các biến cục bộ, ngoài các tham số của nó). Nó không thể in (trừ khi nó gọi một chức năng khác). Nó không thể có một vòng lặp, vòng lặp trong thời gian, một bài kiểm tra (trừ toán tử ternary 3) hoặc thử/ngoại trừ khối.Nếu bạn cần phải làm bất kỳ điều đó, chỉ cần xác định một chức năng thông thường. Trên thực tế, bất cứ khi nào bạn nghĩ rằng bạn muốn sử dụng một lambda, hãy nghĩ hai lần. Mã sẽ không dễ đọc hơn nếu bạn sử dụng chức năng thông thường? Đó không phải là biểu thức Lambda mà bạn muốn sử dụng lại ở một nơi khác trong mã của bạn? Cuối cùng, luôn luôn làm những gì dẫn đến mã dễ đọc và có thể duy trì nhất. Không có sự khác biệt giữa Lambdas và các chức năng bình thường khi có liên quan đến hiệu suất. Xem bây giờ hướng dẫn này có một khóa học video liên quan được tạo bởi nhóm Python thực sự. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn về sự hiểu biết của bạn: Cách sử dụng các chức năng của Python Lambda This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: How to Use Python Lambda Functions Tôi có thể chuyển một chức năng như một đối số trong Python không? Python Lambdas là rất ít, các hàm ẩn danh, chịu một cú pháp hạn chế hơn nhưng ngắn gọn hơn so với các hàm trăn thông thường. Đến cuối bài viết này, bạn sẽ biết:
Hướng dẫn này chủ yếu dành cho các lập trình viên Python trung bình đến có kinh nghiệm, nhưng nó có thể truy cập được cho bất kỳ tâm trí tò mò nào với sự quan tâm đến lập trình và tính toán Lambda. Tất cả các ví dụ bao gồm trong hướng dẫn này đã được thử nghiệm với Python 3.7. Tính toán 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ừ Lambda Tính toán, một mô hình tính toán được phát minh bởi Alonzo Church. Bạn sẽ phát hiện ra khi tính toán Lambda được giới thiệu và tại sao nó lại là một khái niệm cơ bản kết thúc trong hệ sinh thái Python. Lịch sửNhà thờ Alonzo chính thức hóa Tính toán 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 chức năng của Lambda cũng được gọi là Trừu tượng Lambda, một tài liệu tham khảo trực tiếp đến mô hình trừu tượng của sáng tạo ban đầu của Alonzo Church. Tính toán Lambda có thể mã hóa bất kỳ tính toán nào. Nó hoàn thành, nhưng trái với khái niệm về một cỗ máy Turing, nó là tinh khiết và không giữ bất kỳ trạng thái nào. Các ngôn ngữ chức năng có nguồn gốc từ logic toán học và tính toán Lambda, trong khi các ngôn ngữ lập trình bắt buộc nắm lấy mô hình tính toán dựa trên trạng thái được phát minh bởi Alan Turing. Hai mô hình tính toán, máy tính Lambda và máy Turing, có thể được dịch sang nhau. Sự tương đương này được gọi là giả thuyết của nhà thờ. Các ngôn ngữ chức năng trực tiếp thừa hưởng triết lý tính toán Lambda, áp dụng một cách tiếp cận tuyên bố của lập trình nhấn mạnh sự 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 bắt buộc được tìm thấy bằng các ngôn ngữ như Fortran, C hoặc Python. Phong cách bắt buộc bao gồm lập trình với các tuyên bố, thúc đẩy luồng 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 gia đình trình bày 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 đặc điểm chức năng đã thấm vào gia đình ngôn ngữ bắt buộc nói riêng với việc giới thiệu các hàm Lambda trong Java hoặc Python. Python vốn không phải là ngôn ngữ chức năng, nhưng nó đã áp dụng một số khái niệm chức năng từ rất sớm. Vào tháng 1 năm 1994, 4, 5, 6 và toán tử 7 đã được thêm vào ngôn ngữ.Ví dụ đầu tiênDưới đây là một vài ví dụ để cung cấp cho bạn sự thèm ăn cho 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 biểu thị 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ả lại khi gọi.Ngược lại, nếu bạn sử dụng cấu trúc Python Lambda, bạn sẽ nhận được những điều sau: Trong ví dụ trên, biểu thức bao gồm:
Bạn có thể viết một ví dụ được xây dựng hơn một chút, một hàm thêm 4 vào một đối số, như sau:Bạn có thể áp dụng chức năng ở trên cho một đối số bằng cách xung quanh hàm và đối số của nó với dấu ngoặc đơn: >>>
9 lấy một đối số 0 và trả lại khi gọi.
Ngược lại, nếu bạn sử dụng cấu trúc Python Lambda, bạn sẽ nhận được những điều sau: >>>
9 lấy một đối số 0 và trả lại khi gọi.
Ngược lại, nếu bạn sử dụng cấu trúc Python Lambda, bạn sẽ nhận được những điều sau: >>>
9 lấy một đối số 0 và trả lại khi gọi.Chức năng ẩ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, bạn sẽ thấy thuật ngữ chức năng Lambda.lambda function. Theo nghĩa đen, một hàm ẩn danh là một hàm không có tên. Trong Python, một hàm ẩn danh được tạo bằng từ khóa 7. Một cách lỏng lẻo hơn, nó có thể hoặc không được gán một tên. Hãy xem xét một hàm ẩn danh hai đối tượng được xác định với 7 nhưng không bị ràng buộc với một biến. Lambda không được đặt tên:>>>
Hàm ở trên xác định một biểu thức Lambda có hai đối số và trả về tổng của chúng. Khác với việc cung cấp cho bạn phản hồi rằng Python hoàn toàn ổn với hình thức này, nó không dẫn đến bất kỳ việc sử dụng thực tế nào. Bạn có thể gọi chức năng trong trình thông dịch Python: Ví dụ trên là tận dụng tính năng chỉ dành cho trình thông dịch tương tác được cung cấp thông qua dấu gạch dưới ( 3). Xem ghi chú dưới đây để biết thêm chi tiết.Bạn không thể viết mã tương tự trong mô -đun Python. Hãy xem xét 3 trong phiên dịch viên là một tác dụng phụ mà bạn đã tận dụng. Trong một mô -đun Python, bạn sẽ gán một tên cho Lambda hoặc bạn sẽ chuyển Lambda cho một chức năng. Bạn sẽ sử dụng hai cách tiếp cận đó sau trong bài viết này.Một mẫu khác được sử dụng trong các ngôn ngữ khác như JavaScript là ngay lập tức thực hiện hàm Python Lambda. Điều này được gọi là một biểu thức chức năng được gọi ngay lập tức (iife, phát âm là iff iffy). Đây là một ví dụ:Immediately Invoked Function Expression (IIFE, pronounce “iffy”). Here’s an example: >>> 0Hàm ở trên xác định một biểu thức Lambda có hai đối số và trả về tổng của chúng. Khác với việc cung cấp cho bạn phản hồi rằng Python hoàn toàn ổn với hình thức này, nó không dẫn đến bất kỳ việc sử dụng thực tế nào. Bạn có thể gọi chức năng trong trình thông dịch Python: Ví dụ trên là tận dụng tính năng chỉ dành cho trình thông dịch tương tác được cung cấp thông qua dấu gạch dưới ( 3). Xem ghi chú dưới đây để biết thêm chi tiết.Bạn không thể viết mã tương tự trong mô -đun Python. Hãy xem xét 3 trong phiên dịch viên là một tác dụng phụ mà bạn đã tận dụng. Trong một mô -đun Python, bạn sẽ gán một tên cho Lambda hoặc bạn sẽ chuyển Lambda cho một chức năng. Bạn sẽ sử dụng hai cách tiếp cận đó sau trong bài viết này.Một mẫu khác được sử dụng trong các ngôn ngữ khác như JavaScript là ngay lập tức thực hiện hàm Python Lambda. Điều này được gọi là một biểu thức chức năng được gọi ngay lập tức (iife, phát âm là iff iffy). Đây là một ví dụ: >>> 1Hàm ở trên xác định một biểu thức Lambda có hai đối số và trả về tổng của chúng. Khác với việc cung cấp cho bạn phản hồi rằng Python hoàn toàn ổn với hình thức này, nó không dẫn đến bất kỳ việc sử dụng thực tế nào. Bạn có thể gọi chức năng trong trình thông dịch Python:Ví dụ trên là tận dụng tính năng chỉ dành cho trình thông dịch tương tác được cung cấp thông qua dấu gạch dưới ( 3). Xem ghi chú dưới đây để biết thêm chi tiết.
Một mẫu khác được sử dụng trong các ngôn ngữ khác như JavaScript là ngay lập tức thực hiện hàm Python Lambda. Điều này được gọi là một biểu thức chức năng được gọi ngay lập tức (iife, phát âm là iff iffy). Đây là một ví dụ: Hàm Lambda ở trên được xác định và sau đó được gọi ngay lập tức với hai đối số (def add_one(x): return x + 1 6 và >>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}' >>> full_name('guido', 'van rossum') 'Full name: Guido Van Rossum' 6). Nó trả về giá trị >>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}' >>> full_name('guido', 'van rossum') 'Full name: Guido Van Rossum' 7, 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 7 trong Python như một cách ngắn hơn để xác định hàm.Python 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ả từ một biểu thức lambda có thể gọi được, không giống như cơ thể của một chức năng bình thường. >>> 2Hàm ở trên xác định một biểu thức Lambda có hai đối số và trả về tổng của chúng. Khác với việc cung cấp cho bạn phản hồi rằng Python hoàn toàn ổn với hình thức này, nó không dẫn đến bất kỳ việc sử dụng thực tế nào. Bạn có thể gọi chức năng trong trình thông dịch Python: >>> 3Hàm ở trên xác định một biểu thức Lambda có hai đối số và trả về tổng của chúng. Khác với việc cung cấp cho bạn phản hồi rằng Python hoàn toàn ổn với hình thức này, nó không dẫn đến bất kỳ việc sử dụng thực tế nào. Bạn có thể gọi chức năng trong trình thông dịch Python:Ví dụ trên là tận dụng tính năng chỉ dành cho trình thông dịch tương tác được cung cấp thông qua dấu gạch dưới ( 3). Xem ghi chú dưới đây để biết thêm chi tiết.>>> 4TraceBack của một ngoại lệ được nêu ra trong khi hàm Lambda được thực thi chỉ xác định hàm gây ra ngoại lệ là 04.Ở đây, một ngoại lệ tương tự được nâng lên bởi một chức năng bình thường: >>> 5Hàm thông thường gây ra lỗi tương tự nhưng dẫn đến một dấu vết chính xác hơn vì nó cho tên hàm, 07.Cú phápNhư bạn đã thấy trong các phần trước, một biểu mẫu lambda thể hiện sự phân biệt cú pháp từ một hàm bình thường. Cụ thể, một hàm Lambda có các đặc điểm sau:
Không có tuyên bố Một hàm Lambda có thể chứa bất kỳ câu lệnh nào. Trong hàm Lambda, các câu như 7, 09, 10 hoặc 11 sẽ tăng ngoại lệ 12. Ở đây, một ví dụ về việc thêm 10 vào thân máy Lambda:>>> 6Ví dụ giả định này dự định 10 rằng tham số 0 có giá trị 6. Nhưng, trình thông dịch xác định 12 trong khi phân tích mã liên quan đến câu lệnh 10 trong phần thân của 7.Biểu thức đơn Trái ngược với một hàm bình thường, hàm Python lambda là một biểu thức duy nhất. Mặc dù, trong phần thân của 7, bạn có thể truyền biểu thức trên một số dòng bằng dấu ngoặc đơn hoặc chuỗi đa dòng, nó vẫn là một biểu thức duy nhất:>>> 7Ví dụ trên trả về chuỗi 21 khi đối số lambda là lẻ và 22 khi đối số là chẵn. Nó trải trên hai dòng 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ất.Loại chú thích Nếu bạn đã bắt đầu áp dụng gợi ý loại, hiện có sẵn trong Python, thì bạn có một lý do chính đáng khác để thích các chức năng bình thường hơn các chức năng của Python Lambda. Kiểm tra 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 hàm Lambda, không có tương đương cho các điều sau: 8Bất kỳ loại lỗi nào với 23 đều có thể bị bắt bởi các công cụ như 24 hoặc 25, trong khi đó 12 với hàm Lambda tương đương được nâng lên khi chạy: thời gian chạy:>>> 9Giống như cố gắng bao gồm một tuyên bố trong Lambda, việc thêm chú thích loại ngay lập tức dẫn đến 12 khi chạy.Iife 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: >>> 0Bên ngoài phiên dịch viên Python, tính năng này có thể không được sử dụng trong thực tế. Nó có một hậu quả trực tiếp của một chức năng Lambda được gọi là được xác định. Ví dụ: điều này cho phép bạn chuyển định nghĩa của biểu thức Lambda Python cho hàm bậc cao hơn như 4, 5 hoặc 1 hoặc chức năng chính.Tranh luậnGiống như một đối tượng hàm bình thường được xác định với 8, các biểu thức Python Lambda hỗ trợ tất cả các cách khác nhau để truyền đối số. Điêu nay bao gôm:
Các ví dụ sau đây minh họa các tùy chọn mở cho bạn để chuyển các đối số cho các biểu thức Lambda: >>> 1Trang tríTrong Python, một người trang trí là việc thực hiện một mẫu cho phép thêm một hành vi vào một chức năng hoặc một lớp. Nó thường được biểu thị bằng tiền tố cú pháp 32 một hàm. Đây là một ví dụ giả định: 2Trong ví dụ trên, 33 là một hàm thêm hành vi vào 34, do đó gọi 35 dẫn đến kết quả đầu ra sau: 3 34 chỉ in 37, nhưng người trang trí thêm một hành vi bổ sung cũng in 38.Một người trang trí có thể được áp dụng cho một lambda. Mặc dù nó không thể trang trí Lambda với cú pháp 32, một người trang trí chỉ là một chức năng, vì vậy nó có thể gọi hàm Lambda: 4 40, được trang trí với 41 trên dòng 11, được gọi bằng đối số 6 trên dòng 15. Ngược lại, trên dòng 18, một hàm Lambda ngay lập tức được liên quan và nhúng vào một cuộc gọi đến 43, người trang trí. Khi bạn thực thi mã ở trên, bạn có được những điều sau: 5Xem cách, như bạn đã thấy, tên của hàm Lambda xuất hiện là 04, trong khi 45 được xác định rõ ràng cho hàm bình thường.Trang trí chức năng 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 bối cảnh chức năng bậc cao hoặc chức năng chính. Hãy cùng xem một ví dụ với 4: 6Đối số đầu tiên của 4 là một lambda nhân lên đối số của nó với 6. Lambda này được trang trí với 43. Khi được thực thi, ví dụ trên xuất ra sau: 7Kết quả 50 là một danh sách thu được từ việc nhân mỗi phần tử của 51. Hiện tại, hãy xem xét 51 tương đương với danh sách 53.Bạn sẽ được tiếp xúc với 4 chi tiết hơn trong bản đồ.Một lambda cũng có thể là một người trang trí, nhưng nó không được khuyến khích. Nếu bạn thấy mình cần phải làm điều này, hãy tham khảo PEP 8, các khuyến nghị lập trình. Để biết thêm về trang trí Python, hãy xem Primer trên trang trí Python. Khép kínĐóng là một hàm trong đó mọi biến miễn phí, mọi thứ ngoại trừ các 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 đó. Trong thực tế, đóng cửa xác định môi trường mà chúng chạy, và do đó có thể được gọi từ bất cứ đâu. Các khái niệm về lambdas và đóng cửa không nhất thiết phải liên quan, mặc dù các hàm Lambda có thể đóng cửa giống như cách các chức năng bình thường cũng có thể là đóng cửa. Một số ngôn ngữ có cá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à đố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, một đóng cửa được xây dựng với chức năng Python bình thường: 8 55 Trả về 56, một hàm lồng nhau tính tổng của ba đối số:
Để kiểm tra hành vi của 55 và 56, 55 được gọi ba lần trong vòng lặp 66 in như sau: 9Trên dòng 9 của mã, 56 được trả về bởi lời mời của 55 được liên kết với tên 69. Trên dòng 5, 56 nắm bắt 0 và 59 vì nó có quyền truy cập vào môi trường nhúng của nó, do đó khi gọi đóng cửa, nó có thể hoạt động trên hai biến miễn phí 0 và 59.Tương tự, một 7 cũng có thể là một đóng cửa. Ở đây, ví dụ tương tự với chức năng Python Lambda: 0Khi bạn thực thi mã ở trên, bạn có được đầu ra sau: 1Trên dòng 6, 55 trả về một lambda và gán nó cho biến 69. Trên dòng 3, phần thân của hàm Lambda tham chiếu 0 và 59. Biến 59 có sẵn tại thời điểm định nghĩa, trong khi 0 được xác định trong thời gian chạy khi 55 được gọi.Trong tình huống này, cả chức năng bình thường và Lambda đều hoạt động tương tự. Trong phần tiếp theo, bạn sẽ thấy một tình huống trong đó hành vi của Lambda có thể bị lừa dối do thời gian đánh giá của nó (thời gian định nghĩa 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 các vòng lặp, hành vi của một chức năng Python Lambda như một sự đóng cửa 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 bối cảnh của một lambda. Các ví dụ sau đây cho thấy sự khác biệt khi sử dụng hàm thông thường so với sử dụng Lambda Python. Kiểm tra kịch bản trước bằng cách sử dụng chức năng thông thường: >>> 2Trong một hàm bình thường, 83 được đánh giá tại thời điểm định nghĩa, trên dòng 9, khi hàm được thêm vào danh sách: 84.Bây giờ, với việc thực hiện cùng một logic với chức năng Lambda, hãy quan sát hành vi bất ngờ: >>> 3Trong một hàm bình thường, 83 được đánh giá tại thời điểm định nghĩa, trên dòng 9, khi hàm được thêm vào danh sách: 84.Bây giờ, với việc thực hiện cùng một logic với chức năng Lambda, hãy quan sát hành vi bất ngờ: >>> 4Trong một hàm bình thường, 83 được đánh giá tại thời điểm định nghĩa, trên dòng 9, khi hàm được thêm vào danh sách: 84.Bây giờ, với việc thực hiện cùng một logic với chức năng Lambda, hãy quan sát hành vi bất ngờ: Kết quả bất ngờ xảy ra do biến miễn phí def f(x): return x * 2 83, như được triển khai, bị ràng buộc tại thời điểm thực hiện của biểu thức Lambda. Hàm Python Lambda trên dòng 4 là một đóng cửa thu thập def f(x): return x * 2 83, một biến miễn phí bị ràng buộc trong thời gian chạy. Khi chạy, trong khi gọi hàm def f(x): return x * 2 87 trên dòng 7, giá trị của def f(x): return x * 2 83 là def f(x): return x * 2 89.Để khắc phục vấn đề này, bạn có thể chỉ định biến miễn phí theo thời gian định nghĩa như sau:
Hàm Lambda Python hoạt động giống như một hàm bình thường liên quan đến các đối số. Do đó, tham số Lambda có thể được khởi tạo với giá trị mặc định: tham số 83 lấy bên ngoài 83 làm giá trị mặc định. Hàm Python Lambda có thể đã được viết là 92 và có kết quả tương tự. 5 98 Xác định một trường hợp thử nghiệm với ba phương pháp thử nghiệm, mỗi phương pháp trong số họ thực hiện một kịch bản thử nghiệm cho 99 được thực hiện như một hàm Lambda. Việc thực hiện tệp Python 00 có chứa 98 tạo ra những điều sau: 6Đúng như dự đoán, chúng tôi có hai trường hợp thử nghiệm thành công và một lỗi cho 02: kết quả là 7, nhưng kết quả dự kiến là 04. Thất bại này là do một sai lầm có chủ ý trong trường hợp thử nghiệm. Thay đổi kết quả dự kiến từ 04 thành 7 sẽ đáp ứng tất cả các bài kiểm tra cho 98.
Mô -đun 95 trích xuất mã Python tương tác từ 10 để thực hiện các thử nghiệm. Mặc dù cú pháp của các hàm Lambda Python không hỗ trợ một 10 điển hình, nhưng có thể gán một chuỗi cho phần tử 12 của Lambda có tên: 7 95 trong nhận xét DOC của Lambda 99 mô tả các trường hợp thử nghiệm tương tự như trong phần trước.Khi bạn thực hiện các bài kiểm tra qua 15, bạn sẽ nhận được như sau: 8Các kết quả kiểm tra thất bại từ cùng một lỗi được giải thích trong việc thực hiện các thử nghiệm đơn vị trong phần trước. Bạn có thể thêm một 10 vào Python Lambda thông qua một bài tập cho 12 để ghi lại hàm Lambda. Mặc dù có thể, cú pháp Python tốt hơn 10 cho các chức năng bình 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ể muốn tham khảo bắt đầu với thử nghiệm trong Python. Biểu hiện Lambda lạm dụngMột số ví dụ trong bài viết này, nếu được viết trong bối cảnh mã Python chuyên nghiệp, sẽ đủ điều kiện là lạm dụng. Nếu bạn thấy mình đang cố gắng vượt qua một cái gì đó mà một biểu thức Lambda không hỗ trợ, thì đây có lẽ là một dấu hiệu cho thấy một chức năng bình thường sẽ phù hợp hơn. 10 cho biểu thức lambda trong phần trước là một ví dụ tốt. Cố gắng khắc phục thực tế rằng chức năng Python Lambda không hỗ trợ các câu lệnh là một lá cờ đỏ khác.Các phần tiếp theo minh họa một vài ví dụ về việc sử dụng Lambda nên tránh. Những ví dụ đó có thể là các tình huống, trong bối cảnh của Python Lambda, mã thể hiện mô hình sau:
Nâng cao một ngoại lệCố gắng nâng cao một ngoại lệ trong một chiếc Python Lambda sẽ khiến bạn suy nghĩ hai lần. Có một số cách thông minh để làm như vậy, nhưng ngay cả một cái gì đó như sau là tốt hơn để tránh: >>> 9Bởi vì một tuyên bố không chính xác về mặt cú pháp trong cơ thể Python Lambda, cách giải quyết trong ví dụ trên bao gồm trừu tượng hóa cuộc gọi tuyên bố với chức năng chuyên dụng 20. Sử dụng loại cách giải quyết này nên tránh. Nếu bạn gặp loại mã này, bạn nên xem xét việc tái cấu trúc mã để sử dụng chức năng thông thường.Phong cách mật mãNhư trong bất kỳ ngôn ngữ lập trình nào, bạn sẽ tìm thấy mã Python có thể khó đọc vì phong cách được sử dụng. Các chức năng của Lambda, do sự đồng nhất của chúng, có thể có 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: >>> 0Bởi vì một tuyên bố không chính xác về mặt cú pháp trong cơ thể Python Lambda, cách giải quyết trong ví dụ trên bao gồm trừu tượng hóa cuộc gọi tuyên bố với chức năng chuyên dụng 20. Sử dụng loại cách giải quyết này nên tránh. Nếu bạn gặp loại mã này, bạn nên xem xét việc tái cấu trúc mã để sử dụng chức năng thông thường.>>> 1Bởi vì một tuyên bố không chính xác về mặt cú pháp trong cơ thể Python Lambda, cách giải quyết trong ví dụ trên bao gồm trừu tượng hóa cuộc gọi tuyên bố với chức năng chuyên dụng 20. Sử dụng loại cách giải quyết này nên tránh. Nếu bạn gặp loại mã này, bạn nên xem xét việc tái cấu trúc mã để sử dụng chức năng thông thường.>>> 2Bởi vì một tuyên bố không chính xác về mặt cú pháp trong cơ thể Python Lambda, cách giải quyết trong ví dụ trên bao gồm trừu tượng hóa cuộc gọi tuyên bố với chức năng chuyên dụng 20. Sử dụng loại cách giải quyết này nên tránh. Nếu bạn gặp loại mã này, bạn nên xem xét việc tái cấu trúc mã để sử dụng chức năng thông thường.Phong cách mật mãNhư trong bất kỳ ngôn ngữ lập trình nào, bạn sẽ tìm thấy mã Python có thể khó đọc vì phong cách được sử dụng. Các chức năng của Lambda, do sự đồng nhất của chúng, có thể có lợi cho việc viết mã khó đọc. 3Ví dụ Lambda sau đây chứa một số lựa chọn kiểu xấu: 4Mặc dù 31 không chỉ ra một vấn đề cho việc sử dụng các chức năng của Python Lambda trong các thuộc tính, nhưng chúng rất khó đọc và dễ bị lỗi vì sử dụng nhiều chuỗi như 35 và 36.Việc thực hiện đúng 27 sẽ được dự kiến như sau: 5 29 sẽ được viết như sau: 6Theo nguyên tắc chung, trong bối cảnh mã được viết bằng Python, thích các chức năng thường xuyên hơn các 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. Việc sử dụng phù hợp của các biểu thức LambdaLambdas trong Python có xu hướng là chủ đề của những tranh cãi. Một số lập luận chống lại Lambdas trong Python là:
Mặc dù 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 chức năng của 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 đây minh họa các kịch bản 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 xuyên được sử dụng với các hàm tích hợp 4 và 5, cũng như 1, được phơi bày trong mô-đun 43. Ba ví dụ sau đây là minh họa tương ứng về việc sử dụng các chức năng đó với các biểu thức Lambda làm bạn đồng hành:>>> 7Bạn có thể phải đọc mã giống với các ví dụ ở trên, mặc dù có dữ liệu có liên quan hơn. Vì lý do đó, điều quan trọng là phải nhận ra các 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 Lambdas, bạn sẽ học cách chuyển đổi các chức năng bậc cao và Lambdas đi kèm của chúng thành các hình thức 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 hơn lấy tham số 44 làm đối số được đặt tên. 44 nhận được một hàm có thể là 7. Hàm này ảnh hưởng trực tiếp đến thuật toán được điều khiển bởi chính hàm chính. 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 một danh sách các ID được thể hiện dưới dạng chuỗi. Mỗi ID là sự kết hợp của chuỗi 54 và một số. Theo mặc định, sắp xếp danh sách này với chức năng tích hợp 3, sử dụng thứ tự từ vựng vì các yếu tố trong danh sách là chuỗi.Để ảnh hưởng đến việc thực thi sắp xếp, bạn có thể gán Lambda cho đối số được đặt tên 44, sao cho việc sắp xếp sẽ sử dụng số được liên kết với ID:>>> 8Bạn có thể phải đọc mã giống với các ví dụ ở trên, mặc dù có dữ liệu có liên quan hơn. Vì lý do đó, điều quan trọng là phải nhận ra các 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 Lambdas, bạn sẽ học cách chuyển đổi các chức năng bậc cao và Lambdas đi kèm của chúng thành các hình thức thành ngữ khác.Chức năng chính Các hàm chính trong Python là các hàm bậc cao hơn lấy tham số 44 làm đối số được đặt tên. 44 nhận được một hàm có thể là 7. Hàm này ảnh hưởng trực tiếp đến thuật toán được điều khiển bởi chính hàm chính. Dưới đây là một số chức năng chính: 9 2: Phương pháp liệt kê 3, 4, 5: Các chức năng tích hợp 51 và 52: Trong mô -đun thuật toán hàng đợi heap 53Hãy tưởng tượng rằng bạn muốn sắp xếp một danh sách các ID được thể hiện dưới dạng chuỗi. Mỗi ID là sự kết hợp của chuỗi print iterator(lambda x: x / 4 + 12, 100, 5) 54 và một số. Theo mặc định, sắp xếp danh sách này với chức năng tích hợp >>> lambda x, y: x + y 3, sử dụng thứ tự từ vựng vì các yếu tố trong danh sách là chuỗi.Để ảnh hưởng đến việc thực thi sắp xếp, bạn có thể gán Lambda cho đối số được đặt tên 44, sao cho việc sắp xếp sẽ sử dụng số được liên kết với ID:print iterator(lambda x: x / 4 + 12, 100, 5) 60Khung UI >>> 0Bạn có thể phải đọc mã giống với các ví dụ ở trên, mặc dù có dữ liệu có liên quan hơn. Vì lý do đó, điều quan trọng là phải nhận ra các 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 Lambdas, bạn sẽ học cách chuyển đổi các chức năng bậc cao và Lambdas đi kèm của chúng thành các hình thức thành ngữ khác. Một cách tiếp cận khác là sử dụng 7:>>> 1Giải pháp này là sạch hơn, dễ đọc hơn và nhanh hơn để gõ trình thông dịch. Mặc dù thời gian thực hiện ít hơn một chút đối với phiên bản 7, việc thực thi các chức năng một lần nữa có thể hiển thị một lợi thế nhỏ cho phiên bản 67. Thời gian thực hiện của 68 được loại trừ khỏi thời gian thực hiện chung và không nên có bất kỳ tác động nào đến kết quả.Khỉ váĐể thử nghiệm, đôi khi nó cần phải dựa vào kết quả lặp lại, ngay cả khi trong quá trình thực hiện bình thường 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. Hãy nói rằng 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. Nhưng, trong quá trình thực hiện thử nghiệm, bạn cần khẳng định chống lại các giá trị có thể dự đoán theo cách lặp lại. Ví dụ sau đây cho thấy làm thế nào, với chức năng 7, việc vá khỉ có thể giúp bạn: 2Trình quản lý bối cảnh giúp cách điện cách cách điện cho khỉ vá một hàm từ thư viện tiêu chuẩn ( 70, trong ví dụ này). Hàm Lambda được gán cho 71 thay thế hành vi mặc định bằng cách trả về 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 72 theo kiểu 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 72 được thiết lập lại để loại bỏ bất kỳ tác dụng phụ bất ngờ nào có ảnh hưởng đến các lĩnh vực khác của thử nghiệm có thể phụ thuộc vào hành vi mặc định của 72.Các khung kiểm tra đơn vị như 94 và 76 Đưa khái niệm này đến mức độ tinh vi cao hơn.Với 76, vẫn sử dụng hàm 7, cùng một ví dụ trở nên thanh lịch và súc tích hơn: 3Với trận đấu pytest 79, 71 được ghi đè bằng một lambda sẽ trả về giá trị xác định, 81, cho phép xác thực thử nghiệm. Trật trình pytest 79 cho phép bạn kiểm soát phạm vi ghi đè. Trong ví dụ trên, việc gọi 71 trong các thử nghiệm tiếp theo, mà không sử dụng việc vá khỉ, sẽ thực hiện việc thực hiện bình thường của chức năng này.Thực hiện kiểm tra 76 cho kết quả sau: 4Bài kiểm tra vượt qua khi chúng tôi xác nhận rằng 85 đã được thực hiện và kết quả là những kết quả được mong đợi trong bối cảnh thử nghiệm.Giải pháp thay thế cho LambdasMặc dù có những lý do tuyệt vời để sử dụng 7, nhưng có những trường hợp sử dụng nó được cau mày. Vậy các lựa chọn thay thế là gì?Các chức năng bậc cao như 4, 5 và 1 có thể được chuyển đổi thành các hình thức thanh lịch hơn với sự xoắn ốc nhẹ của sự sáng tạo, đặc biệt là với sự hiểu biết danh sách hoặc biểu thức máy phát.Để tìm hiểu thêm về toàn bộ danh sách, hãy xem khi nào nên sử dụng danh sách hiểu trong Python. Để tìm hiểu thêm về các biểu thức máy phát, hãy xem cách sử dụng trình tạo và mang lại trong Python. Bản đồHàm tích hợp 4 có chức năng như một đối số đầu tiên và áp dụng nó cho từng phần tử của đối số thứ hai, một điều không thể sử dụng được. Ví dụ về các vòng lặp 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.iterable. Examples of iterables are strings, lists, and tuples. For more information on iterables and iterators, check out Iterables and Iterators. 4 trả về một trình lặp 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 các chuỗi thành một 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:>>> 5Bạn cần gọi 93 để chuyển đổi trình 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 shell python.Sử dụng danh sách hiểu loại bỏ sự cần thiết phải xác định và gọi chức năng Lambda: >>> 6LọcHàm tích hợp 5, một cấu trúc chức năng cổ điển khác, có thể được chuyển đổi thành một sự hiểu biết danh sách. Nó lấy một vị từ như một đối số đầu tiên và một điều có thể là một đối số thứ hai. Nó xây dựng một trình lặp có chứa tất cả các yếu tố của bộ sưu tập ban đầu thỏa mãn chức năng vị ngữ. Dưới đây, 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 nhất định:>>> 7Lưu ý rằng 5 trả về một trình lặp, do đó cần phải gọi loại 97 tích hợp xây dựng một danh sách được đưa ra một trình lặp.Việc thực hiện thúc đẩy cấu trúc hiểu danh sách đưa ra như sau: >>> 8GiảmKể từ Python 3, 6 đã chuyển từ hàm tích hợp sang hàm mô-đun 43. Như 4 và 5, hai đối số đầu tiên của nó lần lượt là một hàm và có thể lặp lại. 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 yếu tố của ITEBLE, 6 áp dụng chức năng và tích lũy kết quả được trả về khi có thể cạn kiệt.Để áp dụng 6 vào danh sách các cặp và tính tổng của mục đầu tiên của mỗi cặp, bạn có thể viết bài này:>>> 9Một cách tiếp cận thành ngữ hơn khi sử dụng biểu thức trình tạo, làm đối số với 04 trong ví dụ, là như sau:>>> Một cách tiếp cận thành ngữ hơn khi sử dụng biểu thức trình tạo, làm đối số với 04 trong ví dụ, là như sau: 0>>> 1Một cách tiếp cận thành ngữ hơn khi sử dụng biểu thức trình tạo, làm đối số với 04 trong ví dụ, là như sau: 0Một giải pháp hơi khác và có thể làm sạch sẽ loại bỏ sự cần thiết phải truy cập rõ ràng phần tử đầu tiên của cặp và thay vào đó sử dụng giải nén:Việc sử dụng dấu gạch dưới ( 3) là một quy ước Python chỉ ra rằng bạn có thể bỏ qua giá trị thứ hai của cặp.04 có một đối số duy nhất, vì vậy biểu thức máy phát không cần phải ở trong ngoặc đơn. Lambdas Pythonic có hay không? PEP 8, là hướng dẫn kiểu cho mã Python, có nội dung: Luôn sử dụng câu lệnh DEF thay vì câu lệnh gán liên kết biểu thức Lambda trực tiếp với định danh. (Nguồn) Điều này không khuyến khích sử dụng Lambda ràng buộc với một đị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 >>> add_one = lambda x: x + 1 >>> add_one(2) 3 7. Như bạn đã thấy trong các phần trước, các chức năng của Lambda chắc chắn có thể sử 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 chức năng Lambda là hoàn toàn pythonic nếu không có gì có sẵn thêm pythonic. Tôi tránh xa việc xác định ý nghĩa của Pythonic, để 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 mã hóa cá nhân hoặc nhóm của bạn.
Chọn một cách khôn ngoan giữa các chức năng của Lambdas hoặc Python bình thường Tránh sử dụng quá nhiều lambdas Sử dụng lambdas với các chức năng bậc cao hoặc các chức năng khóa Python This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: How to Use Python Lambda Functions Tôi có thể chuyển một chức năng như một đối số trong Python không?Bởi vì các chức năng là các đối tượng, chúng ta có thể truyền chúng như các đối số cho các chức năng khác. Các chức năng có thể chấp nhận các chức năng khác vì các đối số còn được gọi là các hàm bậc cao hơn. Trong ví dụ dưới đây, một lời chào hàm được tạo có chức năng như một đối số.. Functions that can accept other functions as arguments are also called higher-order functions. In the example below, a function greet is created which takes a function as an argument.
Có bao nhiêu đối số có thể được truyền cho chức năng Lambda trong Python?Bạn có thể sử dụng nhiều đối số như bạn muốn trong hàm Lambda, nhưng nó chỉ có thể có một biểu thức. Biểu thức này được đánh giá và trả về kết quả.as many arguments as you want in a lambda function, but it can have only one expression. This expression is evaluated and returned as a result.
Hàm Lambda () được gọi như thế nào?Hàm Lambda, còn được gọi là 'Hàm ẩn danh' giống như hàm Python thông thường nhưng có thể được xác định mà không có tên.Mặc dù các hàm bình thường được xác định bằng cách sử dụng từ khóa DEF, các hàm ẩn danh được xác định bằng cách sử dụng từ khóa Lambda.Tuy nhiên, chúng bị giới hạn trong một dòng biểu thức duy nhất.Anonymous function' is same as a regular python function but can be defined without a name. While normal functions are defined using the def keyword, anonymous functions are defined using the lambda keyword. However,they are restricted to single line of expression.
Bạn có thể chuyển một chức năng ẩn danh như một đối số cho một hàm khác không?Các hàm ẩn danh là các chức năng không có tên.Các hàm ẩn danh có thể được sử dụng như một đối số cho các chức năng khác hoặc như một thực thi chức năng được gọi ngay lập tức.Anonymous functions can be used as an argument to other functions or as an immediately invoked function execution. |