Trong bài viết này, chúng ta đã khám phá cách sử dụng Lambda trong Python để sao chép hành vi của vòng lặp for và cách sử dụng vòng lặp for trong lambda
Mục lục
- Sử dụng vòng lặp for trong lambda
- Thay vòng lặp for bằng lambda
- Lưu ý kết luận
Hãy cho chúng tôi hiểu làm thế nào lambda có thể được sử dụng trong trường hợp này trong Python
Sử dụng vòng lặp for trong lambda
Lambda chỉ có thể bao gồm một biểu thức dòng và vòng lặp for có nhiều dòng [ít nhất 3] trong Python nên lúc đầu, có vẻ khó sử dụng nó trong Lambda
Thủ thuật là viết vòng lặp for trong một biểu thức dòng có thể được thực hiện như sau
[print[x] for x in listx]
Vì đây là biểu thức một dòng, chúng ta có thể trực tiếp đưa biểu thức này vào lambda. Theo mã Python duyệt qua danh sách các số nguyên sử dụng lambda, lần lượt sử dụng vòng lặp for
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
đầu ra
91
12
63
5
Đầu ra như mong đợi
Thay vòng lặp for bằng lambda
Trong tương lai, bạn có thể muốn thay thế vòng lặp for bằng lambda tương ứng [không sử dụng vòng lặp for]. Điều này cũng có thể thực hiện được bằng cách sử dụng đệ quy lambda hoặc sử dụng hàm tích hợp reduce trong Python
Mã Python sau sử dụng hàm lambda cùng với hàm rút gọn để duyệt đệ quy qua danh sách giống như vòng lặp for
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
đầu ra
91 12
63
5
Một cách khác là sử dụng đệ quy lambda. Điều này được thể hiện trong đoạn mã Python sau
list = [59, 47, 7, 17, 45]
f = lambda l: print[l[0]] if len[l] == 1 else print[l[0]] + f[l[1:]]
sum = f[list]
đầu ra
59
47
7
17
45
Đi qua mã Python này để lấy tổng tất cả các phần tử của danh sách bằng lambda giống như vòng lặp for
list = [59, 47, 7, 17, 45]
f = lambda l: l[0] if len[l] == 1 else l[0] + f[l[1:]]
sum = f[list]
print[sum]
đầu ra
________số 8Lưu ý kết luận
Với bài viết này tại OpenGenus, bạn phải có ý tưởng hoàn chỉnh về cách sử dụng vòng lặp for với lambda và thậm chí thay thế vòng lặp for bằng lambda
Bạn có thể tạo danh sách lambda trong vòng lặp python bằng cú pháp sau –
cú pháp
def square[x]: return lambda : x*x listOfLambdas = [square[i] for i in [1,2,3,4,5]] for f in listOfLambdas: print f[]
đầu ra
Điều này sẽ cho đầu ra -
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
0Bạn cũng có thể đạt được điều này bằng cách sử dụng cấu trúc lập trình chức năng có tên là currying.
ví dụ
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
1đầu ra
Điều này sẽ cho đầu ra -
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
0Python 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
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
- Python lambdas ra đời như thế nào
- Làm thế nào lambdas so sánh với các đối tượng chức năng thông thường
- Cách viết hàm lambda
- Hàm nào trong thư viện chuẩn Python tận dụng lambdas
- Khi nào nên sử dụng hoặc tránh các hàm lambda Python
ghi chú. Bạn sẽ thấy một số ví dụ về mã sử dụng
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32 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 list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32Nhữ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 độ trung cấp đến có kinh nghiệm, nhưng nó có thể truy cập được đối với bất kỳ ai có đầu óc tò mò quan tâm đến lập trình và phép tính lambda
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 Lambda
Cá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 là 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,
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34, list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
35, list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
36 và toán tử list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32 đã được thêm vào ngôn ngữVí dụ đầu tiên
Dướ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 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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
38 như sau>>>
91
12
63
5
0list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
39 lấy một đối số 91
12
63
5
20 và trả về nó khi 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
>>>
91
12
63
5
3Trong ví dụ trên, biểu thức bao gồm
- từ khóa.
32list = [91, 12, 63, 5] f = lambda listx: [print[x] for x in listx] f[list]
- Một biến ràng buộc.
2091 12 63 5
- Một cơ thể.
2091 12 63 5
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
91
12
63
5
24 vào một đối số, như sau>>>
91
12
63
5
8Bạ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
>>>
91
12
63
5
9Giả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
91
12
63
5
20 bằng đối số 91
12
63
5
26from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
2Vì 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
>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
3Hàm lambda ở trên tương đương với việc viết cái này
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
3Tấ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 lambdas Python bằng cách liệt kê các đối số và phân tách chúng bằng dấu phẩy [
91
12
63
5
27] nhưng không bao quanh chúng bằng dấu ngoặc đơn>>>
91
12
63
5
2Hàm lambda được gán cho
91
12
63
5
28 nhận hai đối số và trả về một chuỗi nội suy hai tham số 91
12
63
5
29 và from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
90. 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 danh
Cá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
- chức năng ẩn danh
- hàm lambda
- biểu thức lambda
- trừu tượng lambda
- biểu mẫu lambda
- Hàm chữ
Đố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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32. 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 một hàm ẩn danh hai đối số được xác định bằng list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32 nhưng không bị ràng buộc với một biến. Lambda không được đặt tên>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
9Hà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 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
>>>
91 12
63
5
3Ví dụ trên đang 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 qua dấu gạch dưới [
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
93]. 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
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
93 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 [
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
93] được liên kết với biểu thức cuối cùng được đánh giáTrong ví dụ trên,
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
93 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ụ
>>>
91
12
63
5
30Hàm lambda ở trên được xác định và sau đó được gọi ngay với hai đối số [
91
12
63
5
26 và from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
98]. Nó trả về giá trị from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
99, 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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32 trong Python như một cách xác định hàm ngắn hơnPython 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
>>>
91
12
63
5
31Python 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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34, list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
35, 91 12
63
5
33, cũng như các chức năng chính như 91 12
63
5
34, 91 12
63
5
35, 91 12
63
5
36 và 91 12
63
5
37. 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ường
Trí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
Không giống như các biểu mẫu lambda trong các ngôn ngữ khác, nơi chúng thêm chức năng, lambdas Python chỉ là một ký hiệu viết tắt nếu bạn quá lười để xác định một hàm. [Nguồn]
Tuy nhiên, đừng để tuyên bố này ngăn cản bạn sử dụng
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32 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ăng
Tạ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
91 12
63
5
39. 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 [list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32]Mô-đun
91
12
63
5
301 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>>>
91
12
63
5
32Bạn có thể thấy rằng
91
12
63
5
302 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
>>>
91
12
63
5
33Mã 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à
91
12
63
5
303 cho một hàm được xác định bằng list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
38, trong khi hàm lambda Python được xem là list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32Tìm lại
Bạ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à
91
12
63
5
306. Đâ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ị 91
12
63
5
306>>>
91
12
63
5
34Truy 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à
91
12
63
5
306Đây là ngoại lệ tương tự được đưa ra bởi một chức năng bình thường
>>>
91
12
63
5
35Hà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,
91
12
63
5
309cú pháp
Như 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
- Nó chỉ có thể chứa các biểu thức và không thể bao gồm các câu lệnh trong phần thân của nó
- Nó được viết dưới dạng một dòng thực thi
- Nó không hỗ trợ chú thích kiểu
- Nó có thể được gọi ngay lập tức [IIFE]
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ư
91 12
63
5
39, 91
12
63
5
311, 91
12
63
5
312 hoặc 91
12
63
5
313 sẽ đưa ra một ngoại lệ 91
12
63
5
314. Đây là một ví dụ về việc thêm 91
12
63
5
312 vào phần thân của lambda>>>
91
12
63
5
36Ví dụ giả tạo này nhằm mục đích
91
12
63
5
312 rằng tham số 91
12
63
5
20 có giá trị là 91
12
63
5
26. Tuy nhiên, trình thông dịch xác định một 91
12
63
5
314 trong khi phân tích cú pháp mã liên quan đến câu lệnh 91
12
63
5
312 trong phần thân của list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32Biể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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32, bạn có thể trải 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>>>
91
12
63
5
37Ví dụ trên trả về chuỗi
91
12
63
5
323 khi đối số lambda là số lẻ và 91
12
63
5
324 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 bình 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
91
12
63
5
38Bất kỳ lỗi loại nào với
91
12
63
5
325 đều có thể được phát hiện bằng các công cụ như 91
12
63
5
326 hoặc 91
12
63
5
327, trong khi một 91
12
63
5
314 có hàm lambda tương đương được phát hiện trong thời gian chạy>>>
91
12
63
5
39Giố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
91
12
63
5
314 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
>>>
91
12
63
5
80Ngoà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ư
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34, list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
35 hoặc 91 12
63
5
33 hoặc cho một hàm chínhLoại bỏ các quảng cáoTranh luận
Giống như một đối tượng hàm bình thường được định nghĩa bằng
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
38, 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- đối số vị trí
- Đối số được đặt tên [đôi khi được gọi là đối số từ khóa]
- Danh sách biến đối số [thường được gọi là varargs]
- Danh sách biến của các đối số từ khóa
- Đối số chỉ từ khóa
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
>>>
91
12
63
5
81ngườ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
91
12
63
5
334 tiền tố một hàm. Đây là một ví dụ giả tạo91
12
63
5
82Trong ví dụ trên,
91
12
63
5
335 là một hàm bổ sung một hành vi cho 91
12
63
5
336, để việc gọi 91
12
63
5
337 dẫn đến đầu ra sau91
12
63
5
8391
12
63
5
336 chỉ in 91
12
63
5
339, nhưng trình trang trí thêm một hành vi bổ sung cũng in 91
12
63
5
340Một trang trí có thể được áp dụng cho lambda. Mặc dù không thể trang trí lambda bằng cú pháp
91
12
63
5
334, nhưng trình trang trí chỉ là một hàm, vì vậy nó có thể gọi hàm lambda91
12
63
5
8491
12
63
5
342, được trang trí bằng 91
12
63
5
343 trên dòng 11, được gọi với đối số from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
98 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 và được nhúng trong lệnh gọi tới 91
12
63
5
345, trình trang trí. Khi bạn thực thi đoạn mã trên, bạn sẽ nhận được thông tin sau91
12
63
5
85Xem làm thế nào, như bạn đã thấy, tên của hàm lambda xuất hiện dưới dạng
91
12
63
5
306, trong khi 91
12
63
5
347 đượ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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
3491
12
63
5
86Đối số đầu tiên của
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34 là một lambda nhân đối số của nó với 91
12
63
5
26. Lambda này được trang trí bằng 91
12
63
5
345. Khi được thực thi, ví dụ trên xuất ra kết quả như sau91
12
63
5
87Kết quả
91
12
63
5
352 là một danh sách thu được từ việc nhân từng phần tử của 91
12
63
5
353. Hiện tại, coi 91
12
63
5
353 tương đương với danh sách 91
12
63
5
355Bạn sẽ được tiếp xúc với
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34 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ề các công cụ trang trí Python, hãy xem Primer on Python Decorators
Loại bỏ các quảng cáoKhép kín
Bao đó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ể là bao đóng giống như cách mà các hàm bình thường cũng có thể là bao đó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
91
12
63
5
8891
12
63
5
357 trả về 91
12
63
5
358, một hàm lồng nhau tính tổng của ba đối số
20 được truyền dưới dạng đối số cho91 12 63 5
35791 12 63 5
361 là biến cục bộ của91 12 63 5
35791 12 63 5
363 là một đối số được truyền cho91 12 63 5
35891 12 63 5
Để kiểm tra hành vi của
91
12
63
5
357 và 91
12
63
5
358, 91
12
63
5
357 được gọi ba lần trong vòng lặp 91
12
63
5
368 in ra thông tin sau91
12
63
5
89Trên dòng 9 của mã,
91
12
63
5
358 được trả về bởi lời gọi của 91
12
63
5
357 bị ràng buộc với tên 91
12
63
5
371. Ở dòng 5, 91
12
63
5
358 nắm bắt 91
12
63
5
20 và 91
12
63
5
361 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 91
12
63
5
20 và 91
12
63
5
361Tương tự, một
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32 cũng có thể là một bao đóng. Đây là ví dụ tương tự với hàm lambda Python91
12
63
5
90Khi bạn thực thi đoạn mã trên, bạn nhận được đầu ra sau
91
12
63
5
91Ở dòng 6,
91
12
63
5
357 trả về một lambda và gán nó cho biến 91
12
63
5
371. Ở dòng 3, phần thân của hàm lambda tham chiếu đến 91
12
63
5
20 và 91
12
63
5
361. Biến 91
12
63
5
361 có sẵn tại thời điểm xác định, trong khi đó, 91
12
63
5
20 được xác định tại thời điểm chạy khi 91
12
63
5
357 đượ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ể là lừa đảo 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
>>>
91
12
63
5
92Trong một hàm thông thường,
91
12
63
5
385 đượ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. 91
12
63
5
386Bâ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
>>>
91
12
63
5
93Kết quả không mong muốn xảy ra vì biến miễn phí
91
12
63
5
385, 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 nắm bắt 91
12
63
5
385, 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 91
12
63
5
389 trên dòng 7, giá trị của 91
12
63
5
385 là 91
12
63
5
391Để 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
>>>
91
12
63
5
94Mộ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ố
91
12
63
5
385 lấy bên ngoài 91
12
63
5
385 làm giá trị mặc định. Hàm lambda Python có thể đã được viết là 91
12
63
5
394 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
91
12
63
5
385 được đặt tại thời điểm định nghĩaLoại bỏ các quảng cáoKiểm tra Lambda
Lambdas 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ả
91
12
63
5
396 và 91
12
63
5
39791
12
63
5
396Mô-đun
91
12
63
5
396 xử lý các hàm lambda Python tương tự như các hàm thông thường91
12
63
5
9591
12
63
5
800 đị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 91
12
63
5
801 được triển khai dưới dạng hàm lambda. Việc thực thi tệp Python 91
12
63
5
802 chứa 91
12
63
5
800 tạo ra như sau91
12
63
5
96Như 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
91
12
63
5
804. kết quả là from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
99, nhưng kết quả dự kiến là 91
12
63
5
806. 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ừ 91
12
63
5
806 thành from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
99 sẽ đáp ứng tất cả các bài kiểm tra cho 91
12
63
5
80091
12
63
5
397Mô-đun
91
12
63
5
397 trích xuất mã Python tương tác từ 91
12
63
5
812 để 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 91
12
63
5
812 điển hình, nhưng có thể gán một chuỗi cho phần tử 91
12
63
5
814 của một lambda có tên91
12
63
5
9791
12
63
5
397 trong doc comment của lambda 91
12
63
5
801 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
91
12
63
5
817, bạn sẽ nhận được thông tin sau91
12
63
5
98Kế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
91
12
63
5
812 vào một lambda Python thông qua một nhiệm vụ cho 91
12
63
5
814 để 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 91
12
63
5
812 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 Lambda
Mộ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.
91
12
63
5
812 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
- Nó không tuân theo hướng dẫn kiểu Python [PEP 8]
- Nó rườm rà và khó đọc
- Nó thông minh một cách không cần thiết với chi phí khó đọc
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
>>>
91
12
63
5
99Vì 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
91
12
63
5
822. 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
>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
20Dấu gạch dưới [
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
93] đề 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 from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
93 đề 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>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
21Phả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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32, 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>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
22Đ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ế
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34 và list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32 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 Python
Bạ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 hiển thị mã Python độc đáo dựa trên
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32. Ví dụ: thay vì triển khai 91
12
63
5
829 như một chức năng thông thường, nó sử dụng một list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32. Tương tự, 91
12
63
5
831 và 91
12
63
5
832 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ườngfrom functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
23Chạy một công cụ như
91
12
63
5
833, một công cụ thực thi hướng dẫn kiểu, sẽ hiển thị các lỗi sau cho 91
12
63
5
829 và 91
12
63
5
835from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
24Mặc dù
91
12
63
5
833 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ư 91
12
63
5
837 và 91
12
63
5
838Việc triển khai đúng
91
12
63
5
829 sẽ được mong đợi như saufrom functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
2591
12
63
5
831 sẽ được viết như saufrom functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
26Theo 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 Lambda
Lambdas 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à
- Các vấn đề về khả năng đọc
- Việc áp đặt một cách suy nghĩ chức năng
- Cú pháp nặng với từ khóa
32list = [91, 12, 63, 5] f = lambda listx: [print[x] for x in listx] f[list]
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ển
Các hàm lambda thường được sử dụng với các hàm tích hợp sẵn
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34 và list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
35, cũng như 91 12
63
5
33, được cung cấp trong mô-đun 91
12
63
5
845. 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>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
27Bạ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ính
Các hàm chính trong Python là các hàm bậc cao lấy tham số
91
12
63
5
846 làm đối số được đặt tên. 91
12
63
5
846 nhận một chức năng có thể là một list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32. 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
34. phương pháp liệt kê91 12 63 5
35,91 12 63 5
36,91 12 63 5
37. Chức năng tích hợp sẵn91 12 63 5
853 và91 12 63 5
854. trong mô-đun thuật toán hàng đợi Heap91 12 63 5
85591 12 63 5
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
91
12
63
5
856 và một số. Sắp xếp danh sách này bằng hàm tích hợp sẵn 91 12
63
5
35, 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à
91
12
63
5
846, sao cho việc sắp xếp sẽ sử dụng số được liên kết với ID>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
28Khung giao diện người dùng
Cá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 để phản hồ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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32 được gán cho lệnh của nút Đảo ngượcfrom functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
29Nhấ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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32 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, việc sử dụng list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32 trở nên độc lập và ít dài dòng hơn 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 Python
Khi 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
91
12
63
5
862
91
12
63
5
Theo tinh thần giống như thử nghiệm trong trình thông dịch Python, mô-đun
91
12
63
5
862 cung cấp các hàm tính thời gian cho các đoạn mã nhỏ. 91
12
63
5
864 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ụ>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
30Khi câu lệnh được truyền dưới dạng chuỗi,
91
12
63
5
865 cần 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ệ 91
12
63
5
866Một cách tiếp cận khác là sử dụng một
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
31Giả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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32, 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 91
12
63
5
869. Thời gian thực hiện của 91
12
63
5
870 đượ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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32, bản vá khỉ có thể giúp bạnfrom functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
32Trì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 [
91
12
63
5
872, trong ví dụ này]. Hàm lambda được gán cho 91
12
63
5
873 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
91
12
63
5
874 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 91
12
63
5
874 đượ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 91
12
63
5
874Các khung kiểm tra đơn vị như
91
12
63
5
396 và 91
12
63
5
878 đưa khái niệm này lên một mức độ phức tạp cao hơnVới
91
12
63
5
878, vẫn sử dụng hàm list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32, ví dụ tương tự trở nên thanh lịch và ngắn gọn hơnfrom functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
33Với vật cố định pytest
91
12
63
5
881, 91
12
63
5
873 được ghi đè bằng lambda sẽ trả về một giá trị xác định, 91
12
63
5
883, cho phép xác thực thử nghiệm. Vật cố định pytest 91
12
63
5
881 cho phép bạn kiểm soát phạm vi ghi đè. Trong ví dụ trên, việc gọi 91
12
63
5
873 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 bài kiểm tra
91
12
63
5
878 cho kết quả như saufrom functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
34Bài kiểm tra đã vượt qua khi chúng tôi xác nhận rằng
91
12
63
5
887 đã được thực hiện và kết quả là kết quả mong đợi trong bối cảnh của bài kiểm traLoại bỏ các quảng cáoCác lựa chọn thay thế cho Lambda
Mặc dù có những lý do tuyệt vời để sử dụng
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32, 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ư
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34, list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
35 và 91 12
63
5
33 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 dựng sẵn
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34 lấy một hàm làm đối số đầu tiên và áp dụng nó cho từng phần tử 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à Iteratorslist = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34 trả về một trình vòng 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 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 list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34, như sau>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
35Bạn cần gọi
91
12
63
5
895 để chuyển đổi trình vòng lặp được trả về bởi list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34 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
>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
36Lọc
Hàm dựng sẵn
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
35, một cấu trúc hàm cổ điển khác, có thể được chuyển thành dạng 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>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
37Lưu ý rằng
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
35 trả về một trình vòng lặp, do đó cần phải gọi loại tích hợp sẵn 91
12
63
5
899 để 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
>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
38Giảm
Kể từ Python 3,
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
36 đã chuyển từ chức năng tích hợp sang chức năng mô-đun 91
12
63
5
845. Là list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
34 và list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
35, 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, list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
36 á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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
36 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>>>
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
39Mộ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
91
12
63
5
906 trong ví dụ, như sau>>>
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
30Mộ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
>>>
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
31Việc sử dụng dấu gạch dưới [
from functools import reduce
list = [91, 12, 63, 5]
f = lambda x, y: print[y] if x is None else print[x, y]
a = reduce[f, list]
93] là một quy ước Python chỉ ra rằng bạn có thể bỏ qua giá trị thứ hai của cặp91
12
63
5
906 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
Luôn sử dụng câu lệnh def thay vì câu lệnh gán liên kết trực tiếp biểu thức lambda với mã định danh. [Nguồn]
Đ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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32. 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
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32, 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ận
Bây giờ bạn đã biết cách sử dụng các hàm
list = [91, 12, 63, 5]
f = lambda listx: [print[x] for x in listx]
f[list]
32 của Python và có thể- Viết Python lambdas và sử dụng các chức năng ẩn danh
- Chọn một cách khôn ngoan giữa lambdas hoặc các hàm Python bình thường
- Tránh sử dụng quá nhiều lambdas
- Sử dụng lambdas với các hàm bậc cao hơn hoặc các hàm chính của Python
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, ưu tiên sử dụng
91
12
63
5
912, 91
12
63
5
913 và 91
12
63
5
914 làm biến metasyntactic, thay vì 91
12
63
5
915, 91
12
63
5
916 và 91
12
63
5
917 truyền thốngĐá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
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 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