Trăn lambda xy

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

def add_one(x):
    return x + 1
2 dường như phớt lờ các phương pháp hay nhất về phong cách Python. Điều này chỉ nhằm mục đích minh họa các khái niệm tính toán lambda hoặc để làm nổi bật các khả năng của Python
def add_one(x):
    return x + 1
2

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 độ từ trung cấp đến có kinh nghiệm, nhưng bất kỳ ai có đầu óc tò mò quan tâm đến lập trình và phép tính lambda đều có thể truy cập được.

Tất cả các ví dụ trong hướng dẫn này đã được thử nghiệm với Python 3. 7

Lấy bài kiểm tra. Kiểm tra kiến ​​thức của bạn với bài kiểm tra tương tác “Hàm Python Lambda” của chúng tôi. Sau khi hoàn thành, bạn sẽ nhận được điểm số để có thể theo dõi quá trình học tập của mình theo thời gian

Lấy bài kiểm tra "

Tải xuống miễn phí. Nhận một chương mẫu từ Thủ thuật Python. Cuốn sách chỉ cho bạn các phương pháp hay nhất về Python với các ví dụ đơn giản mà bạn có thể áp dụng ngay lập tức để viết mã Pythonic + đẹp hơn

Phép tính 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 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,

def add_one(x):
    return x + 1
4,
def add_one(x):
    return x + 1
5,
def add_one(x):
    return x + 1
6 và toán tử
def add_one(x):
    return x + 1
2 đã đượ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 thể hiện bằng định nghĩa hàm Python tiêu chuẩn bằng cách sử dụng từ khóa

def add_one(x):
    return x + 1
8 như sau

>>>

>>> def identity(x):
..     return x

def add_one(x):
    return x + 1
9 lấy một đối số
>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
0 và trả về nó khi được 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

>>>

def add_one(x):
    return x + 1
0

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

  • từ khóa.
    def add_one(x):
        return x + 1
    
    2
  • Một biến ràng buộc.
    >>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
    >>> full_name('guido', 'van rossum')
    'Full name: Guido Van Rossum'
    
    0
  • Một cơ thể.
    >>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
    >>> full_name('guido', 'van rossum')
    'Full name: Guido Van Rossum'
    
    0

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

>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
4 vào một đối số, như sau

>>>

def add_one(x):
    return x + 1
5

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

>>>

def add_one(x):
    return x + 1
6

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

>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
0 bằng đối số
>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
6

def add_one(x):
    return x + 1
9

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

>>>

def add_one(x):
    return x + 1
0

Hàm lambda ở trên tương đương với việc viết cái này

def add_one(x):
    return x + 1

Tất cả các chức năng này có một đối số duy nhất. Bạn có thể nhận thấy rằng, trong định nghĩa của lambdas, các đối số không có dấu ngoặc đơn xung quanh chúng. Các hàm đa đối số (các hàm nhận nhiều hơn một đối số) được thể hiện trong Python lambdas bằng cách liệt kê các đối số và phân tách chúng bằng dấu phẩy (

>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
7) nhưng không bao quanh chúng bằng dấu ngoặc đơn

>>>

>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'

Hàm lambda được gán cho

>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
8 nhận hai đối số và trả về một chuỗi nội suy hai tham số
>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
9 và
def add_one(x):
    return x + 1
60. Như mong đợi, định nghĩa của lambda liệt kê các đối số không có dấu ngoặc đơn, trong khi việc gọi hàm được thực hiện chính xác như một hàm Python bình thường, với các dấu ngoặc đơn bao quanh các đối số

Loại bỏ các quảng cá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

def add_one(x):
    return x + 1
2. Nói một cách lỏng lẻo hơn, nó có thể được đặt tên hoặc không. Xem xét hàm ẩn danh hai đối số được xác định bằng
def add_one(x):
    return x + 1
2 nhưng không bị ràng buộc với một biến. Lambda không được đặt tên

>>>

def add_one(x):
    return x + 1
6

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 thông tin phản hồi rằng Python hoàn toàn ổn với biểu mẫu này, nó không dẫn đến bất kỳ ứng dụng thực tế nào. Bạn có thể gọi hàm trong trình thông dịch Python

>>>

def add_one(x):
    return x + 1
0

Ví dụ trên đang tận dụng tính năng tương tác chỉ dành cho trình thông dịch được cung cấp thông qua dấu gạch dưới (

def add_one(x):
    return x + 1
63). 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

def add_one(x):
    return x + 1
63 trong trình thông dịch là tác dụng phụ mà bạn đã lợi dụng. Trong một mô-đun Python, bạn sẽ gán tên cho lambda hoặc bạn sẽ chuyển lambda cho một hàm. Bạn sẽ sử dụng hai cách tiếp cận đó sau trong bài viết này

Ghi chú. Trong trình thông dịch tương tác, dấu gạch dưới đơn (

def add_one(x):
    return x + 1
63) được liên kết với biểu thức cuối cùng được đánh giá

Trong ví dụ trên,

def add_one(x):
    return x + 1
63 trỏ đến hàm lambda. Để biết thêm chi tiết về cách sử dụng ký tự đặc biệt này trong Python, hãy xem Ý nghĩa của dấu gạch dưới trong 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ụ

>>>

def add_one(x):
    return x + 1
00

Hàm lambda ở trên được xác định và sau đó được gọi ngay với hai đối số (

>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
6 và
def add_one(x):
    return x + 1
68). Nó trả về giá trị
def add_one(x):
    return x + 1
69, là tổng của các đối số

Một số ví dụ trong hướng dẫn này sử dụng định dạng này để làm nổi bật khía cạnh ẩn danh của hàm lambda và tránh tập trung vào

def add_one(x):
    return x + 1
2 trong Python như một cách ngắn gọn hơn để xác định hàm

Python không khuyến khích sử dụng các biểu thức lambda được gọi ngay lập tức. Nó chỉ đơn giản là kết quả 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

>>>

def add_one(x):
    return x + 1
01

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

def add_one(x):
    return x + 1
4,
def add_one(x):
    return x + 1
5,
def add_one(x):
    return x + 1
03, cũng như các chức năng chính như ________ 304, ________ 305, ________ 306 và ________ 307. Bạn sẽ sử dụng các hàm lambda cùng với các hàm bậc cao hơn của Python trong phần Sử dụng biểu thức Lambda phù hợ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

def add_one(x):
    return x + 1
2 của Python. Thoạt nhìn, bạn có thể chấp nhận rằng hàm lambda là một hàm có một số đường cú pháp rút ngắn mã để xác định hoặc gọi một hàm. Các phần sau đây nêu bật những điểm tương đồng và khác biệt tinh tế giữa các hàm Python bình thường và hàm 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

def add_one(x):
    return x + 1
09. dưới bề mặt, hầu như không có gì. Hãy xác minh cách Python nhìn thấy một hàm được xây dựng bằng một câu lệnh return duy nhất so với một hàm được xây dựng dưới dạng một biểu thức (
def add_one(x):
    return x + 1
2)

Mô-đun

def add_one(x):
    return x + 1
001 hiển thị các hàm để phân tích mã byte Python do trình biên dịch Python tạo ra

>>>

def add_one(x):
    return x + 1
02

Bạn có thể thấy rằng

def add_one(x):
    return x + 1
002 hiển thị một phiên bản có thể đọc được của mã byte Python cho phép kiểm tra các hướng dẫn cấp thấp mà trình thông dịch Python sẽ sử dụng trong khi thực thi chương trình

Bây giờ hãy xem nó với một đối tượng chức năng thông thường

>>>

def add_one(x):
    return x + 1
03

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à

def add_one(x):
    return x + 1
003 cho một hàm được xác định bằng
def add_one(x):
    return x + 1
8, trong khi hàm lambda Python được xem là
def add_one(x):
    return x + 1
2

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à

def add_one(x):
    return x + 1
006. Đây có thể là một hạn chế cần xem xét khi xảy ra ngoại lệ và truy nguyên chỉ hiển thị
def add_one(x):
    return x + 1
006

>>>

def add_one(x):
    return x + 1
04

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à

def add_one(x):
    return x + 1
006

Đây là ngoại lệ tương tự được đưa ra bởi một chức năng bình thường

>>>

def add_one(x):
    return x + 1
05

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,

def add_one(x):
    return x + 1
009

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ư

def add_one(x):
    return x + 1
09,
def add_one(x):
    return x + 1
011,
def add_one(x):
    return x + 1
012 hoặc
def add_one(x):
    return x + 1
013 sẽ đưa ra một ngoại lệ
def add_one(x):
    return x + 1
014. Đây là một ví dụ về việc thêm
def add_one(x):
    return x + 1
012 vào phần thân của lambda

>>>

def add_one(x):
    return x + 1
06

Ví dụ giả định này nhằm

def add_one(x):
    return x + 1
012 rằng tham số
>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
0 có giá trị là
>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
6. Tuy nhiên, trình thông dịch xác định một
def add_one(x):
    return x + 1
014 trong khi phân tích cú pháp mã liên quan đến câu lệnh
def add_one(x):
    return x + 1
012 trong phần thân của
def add_one(x):
    return x + 1
2

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

def add_one(x):
    return x + 1
2, bạn có thể trải rộng biểu thức trên nhiều dòng bằng cách sử dụng dấu ngoặc đơn hoặc chuỗi nhiều dòng, nó vẫn là một biểu thức duy nhất

>>>

def add_one(x):
    return x + 1
07

Ví dụ trên trả về chuỗi

def add_one(x):
    return x + 1
023 khi đối số lambda là số lẻ và
def add_one(x):
    return x + 1
024 khi đối số là số chẵn. Nó trải rộng trên hai dòng bởi vì nó được chứa trong một tập hợp các dấu ngoặc đơn, nhưng nó vẫn là một biểu thức duy nhấ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 thông thường hơn các hàm lambda của Python. Xem Kiểm tra loại Python (Hướng dẫn) để tìm hiểu thêm về gợi ý loại Python và kiểm tra loại. Trong một hàm lambda, không có tương đương với những điều sau đây

def add_one(x):
    return x + 1
08

Bất kỳ lỗi loại nào với

def add_one(x):
    return x + 1
025 đều có thể được phát hiện bằng các công cụ như
def add_one(x):
    return x + 1
026 hoặc
def add_one(x):
    return x + 1
027, trong khi một
def add_one(x):
    return x + 1
014 có hàm lambda tương đương được đưa ra trong thời gian chạy

>>>

def add_one(x):
    return x + 1
09

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

def add_one(x):
    return x + 1
014 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

>>>

def add_one(x):
    return x + 1
50

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ư

def add_one(x):
    return x + 1
4,
def add_one(x):
    return x + 1
5 hoặc
def add_one(x):
    return x + 1
03 hoặc 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

def add_one(x):
    return x + 1
8, các biểu thức lambda Python hỗ trợ tất cả các cách truyền đối số khác nhau. Điêu nay bao gôm

  • đố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

>>>

def add_one(x):
    return x + 1
51

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

def add_one(x):
    return x + 1
034 tiền tố một hàm. Đây là một ví dụ giả tạo

def add_one(x):
    return x + 1
52

Trong ví dụ trên,

def add_one(x):
    return x + 1
035 là một hàm thêm một hành vi vào
def add_one(x):
    return x + 1
036, để việc gọi
def add_one(x):
    return x + 1
037 dẫn đến đầu ra sau

def add_one(x):
    return x + 1
53

def add_one(x):
    return x + 1
036 chỉ in
def add_one(x):
    return x + 1
039, nhưng trình trang trí thêm một hành vi bổ sung cũng in
def add_one(x):
    return x + 1
040

Một trình trang trí có thể được áp dụng cho lambda. Mặc dù không thể trang trí lambda bằng cú pháp

def add_one(x):
    return x + 1
034, nhưng trình trang trí chỉ là một hàm, vì vậy nó có thể gọi hàm lambda

def add_one(x):
    return x + 1
54

def add_one(x):
    return x + 1
042, được trang trí bằng
def add_one(x):
    return x + 1
043 trên dòng 11, được gọi với đối số
def add_one(x):
    return x + 1
68 trên dòng 15. Ngược lại, ở dòng 18, một hàm lambda ngay lập tức được nhúng vào một lệnh gọi tới
def add_one(x):
    return x + 1
045, trình trang trí. Khi bạn thực thi đoạn mã trên, bạn sẽ nhận được thông tin sau

def add_one(x):
    return x + 1
55

Xem cách, như bạn đã thấy, tên của hàm lambda xuất hiện dưới dạng

def add_one(x):
    return x + 1
006, trong khi
def add_one(x):
    return x + 1
047 đượ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

def add_one(x):
    return x + 1
4

def add_one(x):
    return x + 1
56

Đối số đầu tiên của

def add_one(x):
    return x + 1
4 là một lambda nhân đối số của nó với
>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
6. Lambda này được trang trí bằng
def add_one(x):
    return x + 1
045. Khi được thực thi, ví dụ trên xuất ra kết quả như sau

def add_one(x):
    return x + 1
57

Kết quả

def add_one(x):
    return x + 1
052 là danh sách có được khi nhân từng phần tử của
def add_one(x):
    return x + 1
053. Hiện tại, coi
def add_one(x):
    return x + 1
053 tương đương với danh sách
def add_one(x):
    return x + 1
055

Bạn sẽ được tiếp xúc với

def add_one(x):
    return x + 1
4 chi tiết hơn trong Bản đồ

Lambda cũng có thể là một công cụ trang trí, nhưng nó không được khuyến khích. Nếu bạn thấy mình cần làm điều này, hãy tham khảo PEP 8, Đề xuất lập trình

Để biết thêm về trình trang trí Python, hãy xem Primer on Python Decorators

Loại bỏ các quảng cá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ể đóng theo cách giống như các hàm thông thường cũng có thể đóng. Một số ngôn ngữ có cấu trúc đặc biệt để đóng hoặc lambda (ví dụ: Groovy với một khối mã ẩn danh làm đối tượng Đóng) hoặc biểu thức lambda (ví dụ: biểu thức Java Lambda với tùy chọn giới hạn để đóng)

Đây là một bao đóng được xây dựng bằng hàm Python bình thường

def add_one(x):
    return x + 1
58

def add_one(x):
    return x + 1
057 trả về
def add_one(x):
    return x + 1
058, một hàm lồng nhau tính tổng của ba đối số

  • >>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
    >>> full_name('guido', 'van rossum')
    'Full name: Guido Van Rossum'
    
    0 được truyền dưới dạng đối số cho
    def add_one(x):
        return x + 1
    
    057
  • def add_one(x):
        return x + 1
    
    061 là biến cục bộ của
    def add_one(x):
        return x + 1
    
    057
  • def add_one(x):
        return x + 1
    
    063 là một đối số được truyền cho
    def add_one(x):
        return x + 1
    
    058

Để kiểm tra hành vi của

def add_one(x):
    return x + 1
057 và
def add_one(x):
    return x + 1
058,
def add_one(x):
    return x + 1
057 được gọi ba lần trong vòng lặp
def add_one(x):
    return x + 1
068 in ra thông tin sau

def add_one(x):
    return x + 1
59

Trên dòng 9 của mã,

def add_one(x):
    return x + 1
058 được trả về bởi lời gọi của
def add_one(x):
    return x + 1
057 bị ràng buộc với tên
def add_one(x):
    return x + 1
071. Ở dòng 5,
def add_one(x):
    return x + 1
058 nắm bắt
>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
0 và
def add_one(x):
    return x + 1
061 vì nó có quyền truy cập vào môi trường nhúng của nó, sao cho khi gọi hàm đóng, nó có thể hoạt động trên hai biến tự do
>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
0 và
def add_one(x):
    return x + 1
061

Tương tự, một

def add_one(x):
    return x + 1
2 cũng có thể là một bao đóng. Đây là ví dụ tương tự với hàm lambda Python

def add_one(x):
    return x + 1
60

Khi bạn thực thi đoạn mã trên, bạn nhận được đầu ra sau

def add_one(x):
    return x + 1
61

Ở dòng 6,

def add_one(x):
    return x + 1
057 trả về một lambda và gán nó cho biến
def add_one(x):
    return x + 1
071. Ở dòng 3, phần thân của hàm lambda tham chiếu đến
>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
0 và
def add_one(x):
    return x + 1
061. Biến
def add_one(x):
    return x + 1
061 có sẵn tại thời điểm định nghĩa, trong khi đó,
>>> full_name = lambda first, last: f'Full name: {first.title()} {last.title()}'
>>> full_name('guido', 'van rossum')
'Full name: Guido Van Rossum'
0 được xác định tại thời điểm chạy khi
def add_one(x):
    return x + 1
057 đượ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ể bị đánh lừa do thời gian đánh giá của nó (thời gian xác định so với thời gian chạy)

Thời gian đánh giá

Trong một số tình huống liên quan đến vòng lặp, hành vi của hàm lambda Python dưới dạng bao đóng có thể phản trực giác. Nó đòi hỏi sự hiểu biết khi các biến miễn phí bị ràng buộc trong ngữ cảnh của lambda. Các ví dụ sau minh họa sự khác biệt khi sử dụng hàm thông thường so với sử dụng Python lambda

Kiểm tra kịch bản trước bằng cách sử dụng chức năng thông thường

>>>

def add_one(x):
    return x + 1
62

Trong một chức năng bình thường,

def add_one(x):
    return x + 1
085 được đánh giá tại thời điểm định nghĩa, trên dòng 9, khi chức năng được thêm vào danh sách.
def add_one(x):
    return x + 1
086

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

>>>

def add_one(x):
    return x + 1
63

Kết quả không mong muốn xảy ra vì biến miễn phí

def add_one(x):
    return x + 1
085, khi được triển khai, bị ràng buộc tại thời điểm thực hiện biểu thức lambda. Hàm lambda của Python trên dòng 4 là một bao đóng bắt giữ
def add_one(x):
    return x + 1
085, một biến tự do bị ràng buộc trong thời gian chạy. Khi chạy, trong khi gọi hàm
def add_one(x):
    return x + 1
089 trên dòng 7, giá trị của
def add_one(x):
    return x + 1
085 là
def add_one(x):
    return x + 1
091

Để khắc phục vấn đề này, bạn có thể gán biến tự do tại thời điểm định nghĩa như sau

>>>

def add_one(x):
    return x + 1
64

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ố

def add_one(x):
    return x + 1
085 lấy bên ngoài
def add_one(x):
    return x + 1
085 làm giá trị mặc định. Hàm lambda Python có thể đã được viết là
def add_one(x):
    return x + 1
094 và có kết quả tương tự

Hàm lambda Python được gọi mà không có bất kỳ đối số nào trên dòng 7 và nó sử dụng giá trị mặc định

def add_one(x):
    return x + 1
085 đượ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ả

def add_one(x):
    return x + 1
096 và
def add_one(x):
    return x + 1
097

def add_one(x):
    return x + 1
096

Mô-đun

def add_one(x):
    return x + 1
096 xử lý các hàm lambda Python tương tự như các hàm thông thường

def add_one(x):
    return x + 1
65

def add_one(x):
    return x + 1
500 định nghĩa một trường hợp thử nghiệm với ba phương thức thử nghiệm, mỗi phương thức thực hiện một kịch bản thử nghiệm cho
def add_one(x):
    return x + 1
501 được triển khai dưới dạng hàm lambda. Việc thực thi tệp Python
def add_one(x):
    return x + 1
502 chứa
def add_one(x):
    return x + 1
500 tạo ra như sau

def add_one(x):
    return x + 1
66

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

def add_one(x):
    return x + 1
504. kết quả là
def add_one(x):
    return x + 1
69, nhưng kết quả mong đợi là
def add_one(x):
    return x + 1
506. Thất bại này là do lỗi cố ý trong trường hợp thử nghiệm. Thay đổi kết quả dự kiến ​​từ
def add_one(x):
    return x + 1
506 thành
def add_one(x):
    return x + 1
69 sẽ đáp ứng tất cả các bài kiểm tra cho
def add_one(x):
    return x + 1
500

def add_one(x):
    return x + 1
097

Mô-đun

def add_one(x):
    return x + 1
097 trích xuất mã Python tương tác từ
def add_one(x):
    return x + 1
512 để thực hiện kiểm tra. Mặc dù cú pháp của các hàm lambda Python không hỗ trợ một
def add_one(x):
    return x + 1
512 điển hình, nhưng có thể gán một chuỗi cho phần tử
def add_one(x):
    return x + 1
514 của một lambda có tên

def add_one(x):
    return x + 1
67

def add_one(x):
    return x + 1
097 trong doc comment của lambda
def add_one(x):
    return x + 1
501 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

def add_one(x):
    return x + 1
517, bạn sẽ nhận được thông tin sau

def add_one(x):
    return x + 1
68

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

def add_one(x):
    return x + 1
512 vào một lambda Python thông qua một phép gán cho
def add_one(x):
    return x + 1
514 để ghi lại một hàm lambda. Mặc dù có thể, nhưng cú pháp Python phù hợp hơn với
def add_one(x):
    return x + 1
512 cho các hàm thông thường so với các hàm lambda

Để biết tổng quan toàn diện về thử nghiệm đơn vị trong Python, bạn có thể tham khảo Bắt đầu với thử nghiệm trong Python

Lạm dụng biểu hiện 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.

def add_one(x):
    return x + 1
512 cho biểu thức lambda trong phần trước là một ví dụ điển hình. Cố gắng khắc phục thực tế là hàm lambda Python không hỗ trợ các câu lệnh là một dấu hiệu đỏ khá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

>>>

def add_one(x):
    return x + 1
69

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

def add_one(x):
    return x + 1
522. Nên tránh sử dụng loại giải pháp thay thế này. Nếu bạn gặp loại mã này, bạn nên xem xét cấu trúc lại mã để sử dụng một chức năng thông thườ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

>>>

def add_one(x):
    return x + 1
90

Dấu gạch dưới (

def add_one(x):
    return x + 1
63) đề cập đến một biến mà bạn không cần phải đề cập đến một cách rõ ràng. Nhưng trong ví dụ này, ba
def add_one(x):
    return x + 1
63 đề cập đến các biến khác nhau. Nâng cấp ban đầu cho mã lambda này có thể là đặt tên cho các biến

>>>

def add_one(x):
    return x + 1
91

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

def add_one(x):
    return x + 1
2, một chức năng thông thường sẽ đi một chặng đường dài để làm cho mã này dễ đọc hơn, trải rộng logic trên một vài dòng và lệnh gọi hàm

>>>

def add_one(x):
    return x + 1
92

Điều này vẫn chưa tối ưu nhưng cho bạn thấy một đường dẫn khả thi để tạo mã và đặc biệt là các hàm lambda của Python, dễ đọc hơn. Trong Các lựa chọn thay thế cho Lambdas, bạn sẽ học cách thay thế

def add_one(x):
    return x + 1
4 và
def add_one(x):
    return x + 1
2 bằng cách hiểu danh sách hoặc biểu thức trình tạo. Điều này sẽ cải thiện đáng kể khả năng đọc mã

Lớp học 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 thể hiện mã Python độc đáo dựa trên

def add_one(x):
    return x + 1
2. Ví dụ: thay vì triển khai
def add_one(x):
    return x + 1
529 như một chức năng thông thường, nó sử dụng một
def add_one(x):
    return x + 1
2. Tương tự,
def add_one(x):
    return x + 1
531 và
def add_one(x):
    return x + 1
532 là các thuộc tính cũng được triển khai với các hàm lambda, thay vì các hàm hoặc trình trang trí thông thường

def add_one(x):
    return x + 1
93

Chạy một công cụ như

def add_one(x):
    return x + 1
533, một công cụ thực thi hướng dẫn kiểu, sẽ hiển thị các lỗi sau cho
def add_one(x):
    return x + 1
529 và
def add_one(x):
    return x + 1
535

def add_one(x):
    return x + 1
94

Mặc dù

def add_one(x):
    return x + 1
533 không chỉ ra vấn đề đối với việc sử dụng các hàm lambda Python trong các thuộc tính, nhưng chúng rất khó đọc và dễ bị lỗi do sử dụng nhiều chuỗi như
def add_one(x):
    return x + 1
537 và
def add_one(x):
    return x + 1
538

Việc thực hiện đúng

def add_one(x):
    return x + 1
529 sẽ được mong đợi như sau

def add_one(x):
    return x + 1
95

def add_one(x):
    return x + 1
531 sẽ được viết như sau

def add_one(x):
    return x + 1
96

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
    def add_one(x):
        return x + 1
    
    2

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

def add_one(x):
    return x + 1
4 và
def add_one(x):
    return x + 1
5, cũng như
def add_one(x):
    return x + 1
03, được cung cấp trong mô-đun
def add_one(x):
    return x + 1
545. Ba ví dụ sau đây là minh họa tương ứng về việc sử dụng các hàm đó với các biểu thức lambda làm bạn đồng hành

>>>

def add_one(x):
    return x + 1
97

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ố

def add_one(x):
    return x + 1
546 làm đối số được đặt tên.
def add_one(x):
    return x + 1
546 nhận một chức năng có thể là một
def add_one(x):
    return x + 1
2. Chức năng này ảnh hưởng trực tiếp đến thuật toán do chính chức năng chính điều khiển. Dưới đây là một số chức năng chính

  • def add_one(x):
        return x + 1
    
    04. phương pháp liệt kê
  • def add_one(x):
        return x + 1
    
    05,
    def add_one(x):
        return x + 1
    
    06,
    def add_one(x):
        return x + 1
    
    07. Chức năng tích hợp sẵn
  • def add_one(x):
        return x + 1
    
    553 và
    def add_one(x):
        return x + 1
    
    554. trong mô-đun thuật toán hàng đợi Heap
    def add_one(x):
        return x + 1
    
    555

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

def add_one(x):
    return x + 1
556 và một số. Sắp xếp danh sách này bằng hàm tích hợp sẵn
def add_one(x):
    return x + 1
05, theo mặc định, sử dụng thứ tự từ điển vì các phần tử trong danh sách là các chuỗi

Để tác động đến việc thực thi sắp xếp, bạn có thể gán lambda cho đối số có tên là

def add_one(x):
    return x + 1
546, sao cho việc sắp xếp sẽ sử dụng số được liên kết với ID

>>>

def add_one(x):
    return x + 1
98

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 để đáp ứng với các sự kiện giao diện người dùng

Chương trình Tkinter ngây thơ dưới đây minh họa cách sử dụng

def add_one(x):
    return x + 1
2 được gán cho lệnh của nút Đảo ngược

def add_one(x):
    return x + 1
99

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*

Trăn lambda xy

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

def add_one(x):
    return x + 1
2 là một cách để xử lý các sự kiện kích hoạt, nhưng một chức năng có thể được sử dụng cho cùng một mục đích. Cuối cùng, nó trở nên khép kín và ít dài dòng hơn khi sử dụng
def add_one(x):
    return x + 1
2 khi lượng mã cần thiết rất ngắn

Để khám phá wxPython, hãy xem Cách xây dựng ứng dụng GUI Python với wxPython

Loại bỏ các quảng cá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

def add_one(x): return x + 1 562

Theo tinh thần giống như thử nghiệm trong trình thông dịch Python, mô-đun

def add_one(x):
    return x + 1
562 cung cấp các hàm tính thời gian cho các đoạn mã nhỏ.
def add_one(x):
    return x + 1
564 nói riêng có thể được gọi trực tiếp, chuyển một số mã Python trong một chuỗi. Đây là một ví dụ

>>>

def add_one(x):
    return x + 1
00

Khi câu lệnh được truyền dưới dạng chuỗi,

def add_one(x):
    return x + 1
565 cần có ngữ cảnh đầy đủ. Trong ví dụ trên, điều này được cung cấp bởi đối số thứ hai thiết lập môi trường cần thiết cho chức năng chính được tính thời gian. Không làm như vậy sẽ gây ra một ngoại lệ
def add_one(x):
    return x + 1
566

Một cách tiếp cận khác là sử dụng một

def add_one(x):
    return x + 1
2

>>>

def add_one(x):
    return x + 1
01

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

def add_one(x):
    return x + 1
2, nhưng việc thực hiện lại các chức năng có thể cho thấy một chút lợi thế đối với phiên bản
def add_one(x):
    return x + 1
569. Thời gian thực hiện của
def add_one(x):
    return x + 1
570 được loại trừ khỏi thời gian thực hiện tổng thể và không có bất kỳ tác động nào đến kết quả

khỉ vá

Để thử nghiệm, đôi khi cần phải dựa vào các kết quả có thể lặp lại, ngay cả khi trong quá trình thực thi bình thường của một phần mềm nhất định, các kết quả tương ứng dự kiến ​​sẽ khác nhau hoặc thậm chí là hoàn toàn ngẫu nhiên

Giả sử bạn muốn kiểm tra một chức năng, trong thời gian chạy, xử lý các giá trị ngẫu nhiên. Tuy nhiên, trong quá trình thực hiện thử nghiệm, bạn cần xác nhận các giá trị có thể dự đoán theo cách có thể lặp lại. Ví dụ sau đây cho thấy cách, với hàm

def add_one(x):
    return x + 1
2, bản vá khỉ có thể giúp bạn

def add_one(x):
    return x + 1
02

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 (

def add_one(x):
    return x + 1
572, trong ví dụ này). Hàm lambda được gán cho
def add_one(x):
    return x + 1
573 thay thế hành vi mặc định bằng cách trả về một giá trị tĩnh

Điều này cho phép kiểm tra bất kỳ chức năng nào tùy thuộc vào

def add_one(x):
    return x + 1
574 theo cách có thể dự đoán được. Trước khi thoát khỏi trình quản lý bối cảnh, hành vi mặc định của
def add_one(x):
    return x + 1
574 được thiết lập lại để loại bỏ bất kỳ tác dụng phụ không mong muốn nào có thể ảnh hưởng đến các khu vực khác của thử nghiệm có thể phụ thuộc vào hành vi mặc định của
def add_one(x):
    return x + 1
574

Các khung kiểm tra đơn vị như

def add_one(x):
    return x + 1
096 và
def add_one(x):
    return x + 1
578 đưa khái niệm này lên một mức độ phức tạp cao hơn

Với

def add_one(x):
    return x + 1
578, vẫn sử dụng hàm
def add_one(x):
    return x + 1
2, ví dụ tương tự trở nên thanh lịch và ngắn gọn hơn

def add_one(x):
    return x + 1
03

Với vật cố định pytest

def add_one(x):
    return x + 1
581,
def add_one(x):
    return x + 1
573 được ghi đè bằng lambda sẽ trả về một giá trị xác định,
def add_one(x):
    return x + 1
583, cho phép xác thực thử nghiệm. Vật cố định pytest
def add_one(x):
    return x + 1
581 cho phép bạn kiểm soát phạm vi ghi đè. Trong ví dụ trên, việc gọi
def add_one(x):
    return x + 1
573 trong các thử nghiệm tiếp theo, mà không sử dụng bản vá khỉ, sẽ thực thi chức năng này bình thường

Thực hiện kiểm tra

def add_one(x):
    return x + 1
578 cho kết quả sau

def add_one(x):
    return x + 1
04

Bài kiểm tra vượt qua khi chúng tôi xác nhận rằng

def add_one(x):
    return x + 1
587 đã được thực hiện và kết quả là kết quả mong đợi trong bối cảnh bài kiểm 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

def add_one(x):
    return x + 1
2, nhưng vẫn có những trường hợp việc sử dụng nó bị phản đối. Vì vậy, các lựa chọn thay thế là gì?

Các hàm bậc cao hơn như

def add_one(x):
    return x + 1
4,
def add_one(x):
    return x + 1
5 và
def add_one(x):
    return x + 1
03 có thể được chuyển đổi thành các dạng thanh lịch hơn với một chút sáng tạo, đặc biệt là với khả năng hiểu danh sách hoặc biểu thức trình tạo

Để tìm hiểu thêm về cách hiểu danh sách, hãy xem Khi nào nên sử dụng cách hiểu danh sách trong Python. Để tìm hiểu thêm về các biểu thức trình tạo, hãy xem Cách sử dụng Trình tạo và năng suất trong Python

Bản đồ

Hàm tích hợp sẵn

def add_one(x):
    return x + 1
4 lấy một hàm làm đối số đầu tiên và áp dụng nó cho từng thành phần của đối số thứ hai, một hàm có thể lặp lại. Ví dụ về iterables là chuỗi, danh sách và bộ dữ liệu. Để biết thêm thông tin về iterables và iterators, hãy xem Iterables và Iterators

def add_one(x):
    return x + 1
4 trả về một iterator tương ứng với bộ sưu tập được chuyển đổi. Ví dụ: nếu bạn muốn chuyển đổi danh sách chuỗi thành danh sách mới với mỗi chuỗi được viết hoa, bạn có thể sử dụng
def add_one(x):
    return x + 1
4, như sau

>>>

def add_one(x):
    return x + 1
05

Bạn cần gọi

def add_one(x):
    return x + 1
595 để chuyển đổi trình vòng lặp được trả về bởi
def add_one(x):
    return x + 1
4 thành một danh sách mở rộng có thể được hiển thị trong trình thông dịch trình bao 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

>>>

def add_one(x):
    return x + 1
06

Lọc

Hàm tích hợp sẵn

def add_one(x):
    return x + 1
5, một cấu trúc hàm cổ điển khác, có thể được chuyển đổi thành cách hiểu danh sách. Nó lấy một biến vị ngữ làm đối số đầu tiên và một biến lặp lại làm đối số thứ hai. Nó xây dựng một iterator chứa tất cả các phần tử của tập hợp ban đầu thỏa mãn chức năng vị ngữ. Đây là một ví dụ lọc tất cả các số chẵn trong một danh sách các số nguyên đã cho

>>>

def add_one(x):
    return x + 1
07

Lưu ý rằng

def add_one(x):
    return x + 1
5 trả về một trình vòng lặp, do đó cần gọi loại tích hợp sẵn
def add_one(x):
    return x + 1
599 để 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

>>>

def add_one(x):
    return x + 1
08

Giảm

Kể từ Python 3,

def add_one(x):
    return x + 1
6 đã chuyển từ chức năng tích hợp sang chức năng mô-đun
def add_one(x):
    return x + 1
545. Là
def add_one(x):
    return x + 1
4 và
def add_one(x):
    return x + 1
5, hai đối số đầu tiên của nó lần lượt là một hàm và một hàm lặp. Nó cũng có thể lấy một bộ khởi tạo làm đối số thứ ba được sử dụng làm giá trị ban đầu của bộ tích lũy kết quả. Đối với mỗi phần tử của iterable,
def add_one(x):
    return x + 1
6 áp dụng hàm và tích lũy kết quả được trả về khi iterable cạn kiệt

Để áp dụng

def add_one(x):
    return x + 1
6 cho một danh sách các cặp và tính tổng của phần tử đầu tiên của mỗi cặp, bạn có thể viết

>>>

def add_one(x):
    return x + 1
09

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

def add_one(x):
    return x + 1
606 trong ví dụ, như sau

>>>

def add_one(x):
    return x + 1
0

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

>>>

def add_one(x):
    return x + 1
1

Việc sử dụng dấu gạch dưới (

def add_one(x):
    return x + 1
63) là một quy ước Python chỉ ra rằng bạn có thể bỏ qua giá trị thứ hai của cặp

def add_one(x):
    return x + 1
606 lấy một đối số duy nhất, vì vậy biểu thức trình tạo không cần phải nằm trong dấu ngoặc đơ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

def add_one(x):
    return x + 1
2. Như bạn đã thấy trong các phần trước, các hàm lambda chắc chắn có thể có những công dụng tốt, mặc dù chúng bị hạn chế.

Một cách có thể để trả lời câu hỏi là các hàm lambda hoàn toàn là Pythonic nếu không có gì Pythonic khả dụng hơn. Tôi đang tránh xa việc định nghĩa “Pythonic” nghĩa là gì, để lại cho bạn định nghĩa phù hợp nhất với suy nghĩ của bạn, cũng như phong cách viết mã của cá nhân bạn hoặc nhóm của bạn

Ngoài phạm vi hẹp của Python

def add_one(x):
    return x + 1
2, Cách viết mã Python đẹp bằng PEP 8 là một tài nguyên tuyệt vời mà bạn có thể muốn xem về kiểu mã trong Python

Phần kết luận

Bây giờ bạn đã biết cách sử dụng các hàm

def add_one(x):
    return x + 1
2 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, thích sử dụng

def add_one(x):
    return x + 1
612,
def add_one(x):
    return x + 1
613 và
def add_one(x):
    return x + 1
614 làm biến siêu cú pháp, thay vì truyền thống
def add_one(x):
    return x + 1
615,
def add_one(x):
    return x + 1
616 và
def add_one(x):
    return x + 1
617

Đánh dấu là đã hoàn thành

Xem ngay Hướng dẫn này có một khóa học video liên quan do nhóm Real Python tạo. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn. Cách sử dụng các hàm Lambda của Python

🐍 Thủ thuật Python 💌

Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python

Trăn lambda xy

Gửi cho tôi thủ thuật Python »

Giới thiệu về André Burgaud

Trăn lambda xy
Trăn lambda xy

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à

Trăn lambda xy

Aldren

Trăn lambda xy

Jon

Trăn lambda xy

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

Trăn lambda xy

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