Chúng ta có thể viết vòng lặp trong biểu thức lambda python không?

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

  1. Sử dụng vòng lặp for trong lambda
  2. Thay vòng lặp for bằng lambda
  3. 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ố 8

Lư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]
0

Bạ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]
0

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

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]
32

Nhữ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áo

Mô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
0

list = [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ọi

Ngượ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
3

Trong ví dụ trên, biểu thức bao gồm

  • từ khóa.
    list = [91, 12, 63, 5] 
    f = lambda listx: [print[x] for x in listx]
    f[list]
    
    32
  • Một biến ràng buộc.
    91
    12
    63
    5
    
    20
  • Một cơ thể.
    91
    12
    63
    5
    
    20

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
8

Bạ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
9

Giả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
26

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]
2

Vì 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]
3

Hà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]
3

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 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
2

Hà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áo

Hà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]
9

Hà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
3

Ví 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ết

Bạ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ày

Ghi 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 Python

Mộ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
30

Hà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ơn

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ả 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
31

Python 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ợp

Loại bỏ các quảng cáo

Python 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 lambda

Chứ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
32

Bạ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ình

Bâ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
33

Mã 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]
32

Tì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
34

Truy 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
35

Hà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
309

cú 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
36

Ví 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]
32

Biể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
37

Ví 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ất

Loạ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
38

Bấ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
39

Giố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ạ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

>>>

91
12
63
5
80

Ngoà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ính

Loại bỏ các quảng cáo

Tranh 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
81

ngườ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ạo

91
12
63
5
82

Trong 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 sau

91
12
63
5
83

91
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
340

Mộ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 lambda

91
12
63
5
84

91
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 sau

91
12
63
5
85

Xem 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ường

Trang 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]
34

91
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ư sau

91
12
63
5
87

Kế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
355

Bạ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áo

Khé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
88

91
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ố

  • 91
    12
    63
    5
    
    20 được truyền dưới dạng đối số cho
    91
    12
    63
    5
    
    357
  • 91
    12
    63
    5
    
    361 là biến cục bộ của
    91
    12
    63
    5
    
    357
  • 91
    12
    63
    5
    
    363 là một đối số được truyền cho
    91
    12
    63
    5
    
    358

Để 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 sau

91
12
63
5
89

Trê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
361

Tươ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 Python

91
12
63
5
90

Khi 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ọi

Trong 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
92

Trong 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
386

Bâ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
93

Kế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
94

Mộ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ĩa

Loại bỏ các quảng cáo

Kiể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
397

91
12
63
5
396

Mô-đ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ường

91
12
63
5
95

91
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ư sau

91
12
63
5
96

Như 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
800

91
12
63
5
397

Mô-đ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ên

91
12
63
5
97

91
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ước

Khi 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 sau

91
12
63
5
98

Kế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ác

Cá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

Loại bỏ các quảng cáo

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
99

Vì 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ường

Phong 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]
20

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] đề 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]
21

Phả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ường

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]
23

Chạ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
835

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]
24

Mặ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
838

Việc triển khai đúng

91
12
63
5
829 sẽ được mong đợi 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]
25

91
12
63
5
831 sẽ được viết 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]
26

Theo 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áo

Sử 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
    list = [91, 12, 63, 5] 
    f = lambda listx: [print[x] for x in listx]
    f[list]
    
    32

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]
27

Bạ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

  • 91 12
    63
    5
    
    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ẵn
  • 91
    12
    63
    5
    
    853 và
    91
    12
    63
    5
    
    854. trong mô-đun thuật toán hàng đợi Heap
    91
    12
    63
    5
    
    855

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]
28

Khung 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ược

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]
29

Nhấ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áo

Trì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

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]
30

Khi 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
866

Mộ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]
31

Giả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ạ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]
32

Trì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
874

Cá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ơn

Vớ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ơ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]
33

Vớ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ường

Thực hiện bài kiểm tra

91
12
63
5
878 cho kết quả 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]
34

Bà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 tra

Loại bỏ các quảng cáo

Cá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à Iterators

list = [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]
35

Bạ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 Python

Sử 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]
36

Lọ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]
37

Lư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ặp

Việ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]
38

Giả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]
39

Mộ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]
30

Mộ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]
31

Việ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ặp

91
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 đơn

Lambdas 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 Python

Phầ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ẻ Email

Bà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

Biểu thức lambda có thể chứa các câu lệnh Python không?

Cụ thể, 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.

Hạn chế của hàm lambda trong Python là gì?

Nhược điểm của hàm lambda. .
Các hàm lambda chỉ có thể có một biểu thức
Hàm lambda không thể có chuỗi tài liệu
Nhiều lần các hàm lambda làm cho mã khó đọc. Ví dụ: xem các khối mã được cung cấp bên dưới

Bạn có thể đặt một vòng lặp trong một vòng lặp Python không?

Các vòng lặp có thể được lồng vào nhau trong Python , như chúng có thể làm với các ngôn ngữ lập trình khác. Đầu tiên chương trình gặp vòng lặp bên ngoài, thực hiện lần lặp đầu tiên của nó. Lần lặp đầu tiên này kích hoạt vòng lặp lồng nhau bên trong, vòng lặp này sẽ chạy cho đến khi hoàn thành.

Python lambda có thể có nhiều câu lệnh không?

Hàm lambda không cho phép nhiều câu lệnh , tuy nhiên, chúng ta có thể tạo hai hàm lambda rồi gọi hàm lambda kia làm tham số cho hàm đầu tiên.

Chủ Đề