Tracks
Hàm lambda trong Python là công cụ mạnh mẽ, gọn nhẹ để tạo nhanh các hàm nhỏ, ẩn danh. Chúng rất phù hợp để đơn giản hóa các tác vụ ngắn hạn, tinh gọn mã với các hàm bậc cao như map, filter hoặc sorted, và giảm lộn xộn khi định nghĩa logic tạm thời hoặc dùng một lần. Chúng cũng mang đến giải pháp tinh tế để cải thiện khả năng đọc mã trong các tình huống đơn giản. Bài viết này sẽ khám phá hàm lambda là gì, đặc điểm của chúng và cách sử dụng hiệu quả.
Trong hướng dẫn này, chúng tôi sẽ cung cấp cái nhìn toàn diện về hàm lambda trong Python, bao gồm cơ chế, cú pháp và cách chúng so sánh với hàm thông thường, kèm các ví dụ đơn giản để minh họa những khái niệm chính. Chúng tôi khám phá các trường hợp sử dụng phổ biến, như dùng hàm lambda trong các mô hình lập trình hàm và hiệu năng của chúng so với hàm chuẩn. Các ví dụ thực tiễn và phương pháp hay nhất được bao gồm để giúp bạn tích hợp hiệu quả hàm lambda vào lập trình Python của bạn.
Hàm Lambda trong Python là gì?
Hàm lambda khác với các hàm Python tiêu chuẩn ở một số điểm quan trọng. Chúng là các biểu thức ẩn danh, nghĩa là không có tên trừ khi được gán rõ ràng cho một biến. Chúng cũng ngắn gọn hơn và được định nghĩa trên một dòng mà không cần câu lệnh return. Điều này khiến chúng lý tưởng cho các thao tác đơn giản, dùng một lần và để dùng làm đối số nội tuyến trong các hàm bậc cao như map, filter và sorted.
Dưới đây là một ví dụ về hàm lambda cộng hai số:
fn = lambda x, y: x + y
print(fn)
# <function <lambda> at 0xe508b8>
Cách hoạt động của hàm lambda
Hàm lambda này hoạt động như thế nào? Để hiểu, hãy so sánh với một hàm Python tiêu chuẩn.
# Example: add two numbers using standard Python function
def add_numbers(x, y):
return x + y
Hàm tiêu chuẩn này khá trực quan. Từ khóa def định nghĩa hàm nhận hai đối số x và y. Nó tính tổng của x và y rồi trả về kết quả.
Bây giờ, hãy xem hàm lambda của chúng ta thực hiện cùng tác vụ như thế nào.
# Example: add two numbers using a lambda function
fn = lambda x, y: x + y
print(fn)
# <function <lambda> at 0xbfb968>
Từ khóa lambda cho biết chúng ta đang định nghĩa một hàm lambda, loại bỏ nhu cầu dùng từ khóa def. Theo sau lambda là các đối số đầu vào x và y. Sau dấu hai chấm, chúng ta chỉ định biểu thức có kết quả sẽ được trả về, x + y.
Viết hàm Lambda trong Python: Ví dụ
Để giúp bạn nắm vững các khái niệm đã đề cập, hãy xem một vài ví dụ về cách hàm Lambda hoạt động trong Python.
Hướng dẫn từng bước để viết hàm lambda
Hàm lambda lý tưởng để tạo các hàm ngắn, đơn giản, không cần thêm độ phức tạp.
Ví dụ, giả sử bạn muốn kiểm tra một số nguyên khác 0 có phải số chẵn hay không. Bạn có thể viết một hàm Python tiêu chuẩn, nhưng cùng chức năng có thể đạt được bằng một hàm lambda một dòng gọn gàng gán cho biến: is_even = lambda x: x % 2 == 0.
Ở đây, hàm lambda bên phải phép gán nhận đầu vào x và trả về True nếu x là số chẵn (tức là phần dư khi chia cho 2 bằng 0).
Hàm lambda này sau đó được gán cho biến is_even, cho phép gọi như một hàm thông thường. Chẳng hạn, is_even(5) (trả về False) và is_even(678432) (trả về True).
Hàm lambda cũng rất hữu ích để định nghĩa các công thức đơn giản. Ví dụ, để đổi từ Celsius sang Fahrenheit, bạn có thể dùng một hàm lambda: c_to_f = lambda c: (c * 9/5) + 32. Sau đó gọi hàm như các hàm khác: c_to_f(0).
Các trường hợp sử dụng phổ biến cho hàm lambda
Hàm lambda thường được dùng trong lập trình hàm, đặc biệt với các hàm như map() và filter(), vốn nhận các hàm khác làm đối số để xử lý phần tử trong một tập hợp. Hãy xem cách dùng hàm lambda với filter(). Đây là một đoạn mã:
# Use filter with lambda function
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
evens = filter(lambda x: x % 2 == 0, numbers)
print(list(evens)) # print the list of the filter object to see the result
# [2, 4, 6, 8]
Trong đoạn mã này, chúng ta bắt đầu bằng cách định nghĩa một tập numbers. Tiếp theo, tạo một hàm lambda để kiểm tra một số có phải số chẵn không. Hàm filter áp dụng hàm lambda này lên tập numbers. Sau đó, chúng ta in danh sách các số chẵn được filter xác định.
Tương tự, chúng ta có thể dùng hàm map để áp dụng một lambda lên một tập phần tử. Trong ví dụ dưới đây, chúng ta tính độ dài chuỗi trong một danh sách bằng cách ánh xạ hàm len() lên từng phần tử.
# Use map with lambda function
fruits = ['apple', 'banana', 'cherry']
lengths = list(map(lambda x: len(x), fruits))
print(lengths)
# [5, 6, 6]
Hàm lambda cũng được dùng với hàm sorted(), hàm này sắp xếp các phần tử của một tập hợp và trả về một tập hợp mới. Trong ví dụ sau (không dùng lambda), chúng ta dùng sorted() để sắp xếp một danh sách số.
numbers = [1, 10, -1, 3, -10, 5]
sorted_stuff = sorted(numbers)
print(sorted_stuff)
# [-10, -1, 1, 3, 5, 10]
Giả sử chúng ta muốn sắp xếp danh sách số theo giá trị tuyệt đối. Làm thế nào để thực hiện? Hàm sorted() có đối số key cho phép tùy chỉnh thứ tự sắp xếp bằng cách cung cấp một hàm lambda.
# Sort according to absolute value
sorted_numbers_absolute = sorted(numbers, key=lambda x: abs(x))
print(sorted_numbers_absolute)
# [1, -1, 3, 5, 10, -10]
Một trường hợp sử dụng khác cho sort() với hàm lambda là sắp xếp một danh sách các bộ giá trị theo một phần tử cụ thể, chẳng hạn phần tử thứ hai.
# Sort a list of tuples by the second element
data = [(1, 3), (2, 1), (4, 2)]
sorted_data = sorted(data, key=lambda x: x[1])
print(sorted_data)
# [(2, 1), (4, 2), (1, 3)]
Trong đoạn mã này, chúng ta định nghĩa data là một danh sách các bộ. Sau đó dùng hàm sorted() với tham số key, trong đó một hàm lambda trích xuất phần tử thứ hai của mỗi bộ để sắp xếp.
Hàm Lambda có nhanh hơn trong Python không?
Trong Python, hàm lambda không mặc định nhanh hơn hàm tiêu chuẩn, vì cả hai đều được biên dịch thành bytecode tương tự. Tuy nhiên, chúng có thể giảm nhẹ chi phí trong các trường hợp mà việc định nghĩa một hàm đầy đủ sẽ thêm phần khuôn mẫu không cần thiết.
Dưới đây là một vài trường hợp thử nghiệm so sánh hàm lambda với hàm Python tiêu chuẩn. Mã được chạy trên máy tính xách tay của tôi, MacBook Pro với chip Apple M1 Pro, 16 GB bộ nhớ, chạy macOS Sequoia 15.2.
Hàm lambda có thể được dùng nội tuyến như các hàm ẩn danh khi truyền trực tiếp vào các hàm bậc cao như map(), filter() hoặc sorted(). Điều này tránh phải định nghĩa và tham chiếu đến một hàm có tên riêng, giảm cả mã khuôn mẫu và chi phí tra cứu.
import time
numbers = list(range(1, 1000000))
# Standard function
def double_standard(x):
return x * 2
start = time.time()
map(double_standard, numbers)
print(time.time() - start)
# Lambda function
double_lambda = map(lambda x: x * 2, numbers)
start = time.time()
list(map(lambda x: x * 2, numbers))
print(time.time() - start)
# 3.504753112792969e-05
# 2.384185791015625e-05
Hàm lambda lý tưởng cho việc dùng một lần hoặc tạm thời, vì chúng loại bỏ nhu cầu có khối def chính thức, tiết kiệm cả thời gian và không gian. Trong khối mã sau, chúng ta so sánh hiệu năng của hàm tiêu chuẩn với hàm lambda. Chúng ta sắp xếp một từ điển với một triệu phần tử, trong đó khóa là mã hai chữ cái ngẫu nhiên và giá trị là số nguyên ngẫu nhiên.
import random
import string
# Generate a dictionary with elements of the form 'XX': number.
NUMBER_ITEMS = 1000000
items = {
''.join(random.choices(string.ascii_uppercase, k=2)): random.randint(1, 100)
for _ in range(NUMBER_ITEMS)
}
# Standard function (extra definition step)
def sort_standard(item):
return item[1]
print('Standard')
start = time.time()
sorted_items_standard = sorted(items, key=sort_standard)
print(time.time() - start)
print(sorted_items_standard[:5])
print()
# Lambda function
print('Lambda')
start = time.time()
sorted_items_lambda = sorted(items, key=lambda x: x[1])
print(time.time() - start)
print(sorted_items_lambda[:5])
print()
# Standard
# 0.00011610984802246094
# ['OA', 'VA', 'XA', 'IA', 'BA']
# Lambda
# 0.00011014938354492188
# ['OA', 'VA', 'XA', 'IA', 'BA']
Hàm Lambda trong Python: Ví dụ và thực hành
Hãy cùng thực hành thêm một số ví dụ để minh họa cách hàm Lambda hoạt động trong Python.
Ví dụ thực tiễn
Hàm lambda thường được dùng với các phương thức dựng sẵn của Python. Chẳng hạn, hãy xem cách dùng reduce() để áp dụng một hàm nhị phân do người dùng định nghĩa lên dãy phần tử một cách tích lũy.
# Example: Use lambda function with built-in Python method reduce.
from functools import reduce
numbers = [5, -6, 2, 7]
total = reduce(lambda x, y: x + y, numbers)
print(f'The sum of the numbers is {total}.')
# The sum of the numbers is 8.
Tương tự filter() hoặc map() ở trên, reduce() áp dụng một hàm, ở đây là lambda, lên một tập phần tử.
Bây giờ, hãy khám phá một hàm dựng sẵn khác của Python, zip(). Hàm zip ghép cặp các phần tử tương ứng từ nhiều danh sách thành các bộ. Ví dụ, kết quả của zip(['a', 'b', 'c'], [1, 2, 3]) là [('a', 1), ('b', 2), ('c', 3)].
# Example: Use lambda function with built-in Python method zip.
list1 = [1, 2, 3]
list2 = [4, 5, 6]
# Using zip and a lambda function to multiply corresponding elements
result = list(map(lambda x: x[0] * x[1], zip(list1, list2)))
print(f'The result of multiplying corresponding elements is {result}.')
# The result of multiplying corresponding elements is [4, 10, 18].
Đoạn mã này tính tích của các phần tử tương ứng từ hai danh sách, list1 và list2. Nó dùng zip() để ghép phần tử từ hai danh sách thành các bộ, sau đó áp dụng một hàm lambda với map() để nhân các phần tử đã ghép, và cuối cùng chuyển kết quả thành danh sách.
Ví dụ thực tế: chuyển đổi dữ liệu
Hãy tưởng tượng bạn điều hành một quầy hoa quả và muốn tính tổng doanh số cho từng loại trái cây.
Trước tiên, chúng ta tạo một vài bản ghi bán hàng. Sau đó, chúng ta dùng map() với một hàm lambda để tính total_sales bằng cách nhân giá và số lượng cho mỗi mặt hàng trong từ điển sales_data. Cú pháp **record bung (unpack) từ điển gốc, đảm bảo tất cả khóa và giá trị của nó được giữ lại trong từ điển mới. Cuối cùng, chúng ta in từng bản ghi của dữ liệu đã chuyển đổi.
# Sample data: list of dictionaries representing sales records
sales_data = [
{'fruit': 'peaches', 'price': 1.41, 'quantity': 3},
{'fruit': 'pears', 'price': 1.21, 'quantity': 2},
{'fruit': 'mangoes', 'price': 0.56, 'quantity': 3},
]
# Using a lambda function to calculate total sales for each record
transformed_data = list(
map(
lambda entry: {**entry, 'total_sales': round(entry['price'] * entry['quantity'], 2)},
sales_data
)
)
# Print the transformed data
for record in transformed_data:
print(record)
# {'fruit': 'peaches', 'price': 1.41, 'quantity': 3, 'total_sales': 4.23}
# {'fruit': 'pears', 'price': 1.21, 'quantity': 2, 'total_sales': 2.42}
# {'fruit': 'mangoes', 'price': 0.56, 'quantity': 3, 'total_sales': 1.68}
Bài tập đơn giản để bạn luyện tập với hàm lambda
Nếu bạn muốn luyện tập dùng hàm lambda, dưới đây là một số bài để thử.
- Cho một số, hãy tìm bình phương của nó.
- Cho hai số, hãy tìm số lớn hơn.
- Cho một số, kiểm tra xem nó có phải số lẻ không.
- Cho một danh sách số nguyên dương, lọc ra tất cả số lẻ.
- Sắp xếp một danh sách các bộ 3 phần tử theo phần tử thứ ba của chúng.
- Trích xuất tên miền từ địa chỉ email. Ví dụ, với
user@example.com, trích xuấtexample.com.
Những lỗi thường gặp liên quan đến lambda
Hãy xem một số lỗi phổ biến khi lập trình viên dùng lambda và cách khắc phục.
1. Lỗi đầu tiên là dùng hàm lambda khi không phù hợp. Cần nhớ rằng hàm lambda được thiết kế cho các tác vụ ngắn, đơn giản, không phải để xử lý logic phức tạp. Ví dụ, đoạn mã sau không phải trường hợp sử dụng lý tưởng cho hàm lambda.
# Complex logic in a lambda
result = lambda x: (x ** 2 + x - 1) / (x + 1 if x != -1 else 1)
print(result(5)) # Hard to understand
# 4.833333333333333
Trong trường hợp này, tốt hơn là chỉ cần dùng một hàm Python tiêu chuẩn.
def complex_logic(x):
if x == -1:
return x ** 2 + x - 1
return (x ** 2 + x - 1) / (x + 1)
print(complex_logic(5))
# 4.833333333333333
2. Một lỗi đơn giản khác là nhầm lẫn cú pháp. Ví dụ, quên từ khóa lambda sẽ dẫn đến lỗi. Một lỗi cú pháp phổ biến khác là bỏ qua đối số đầu vào:
# Forgetting the required arguments
numbers = [1, 2, 3, 4]
squared = map(lambda: x ** 2, numbers) # <-- Where is the input argument? Error: lambda missing argument
Cách khắc phục là bao gồm đối số đầu vào:
squared = map(lambda x: x ** 2, numbers)
Một cách hay để bắt lỗi như vậy là thêm các ca kiểm thử đơn giản, không chính thức khi phát triển.
print(list(squared))
3. Một lỗi khác cần chú ý là không xử lý các trường hợp biên. Ví dụ, đoạn mã này sẽ lỗi khi y bằng 0. Cách khắc phục là thêm một câu lệnh if đơn giản để bắt trường hợp gây lỗi hoặc bọc mã trong khối ngoại lệ.
# Dividing without handling zero
divide = lambda x, y: x / y
safe_divide = lambda x, y: x / y if y != 0 else "undefined"
print(safe_divide(5, 0))
# undefined
4. Một vấn đề tinh vi hơn là quên chuyển đổi iterator thành danh sách khi xuất kết quả. Chẳng hạn, hàm map() trả về một đối tượng map, không phải danh sách. Để truy cập kết quả, hãy chuyển đối tượng map thành list.
# Forgetting to convert to a list
numbers = [1, 2, 3]
squared = map(lambda x: x ** 2, numbers)
print(squared) # <-- squared is the map, not the result
# <map object at 0x106d2b0>
print(list(squared)) # list(squared) gives the result
# [1, 4, 9]
Chiến lược gỡ lỗi hàm Lambda trong Python
Vậy chúng ta gỡ lỗi các hàm lambda như thế nào? Dưới đây là một số cách.
- Phân rã lambda. Tạm thời chuyển nó thành một hàm có tên để phục vụ gỡ lỗi.
- Dùng câu lệnh print để hiển thị các giá trị trung gian trong các hàm bậc cao như
map()hoặcfilter(). - Kiểm thử các trường hợp biên. Kiểm thử với giá trị cực đoan, không hợp lệ hoặc ở ranh giới để bắt lỗi tiềm ẩn.
Một mẹo hữu ích để in các bước trung gian là đưa câu lệnh print vào trong một bộ (tuple) cùng với kết quả. Đầu ra mong muốn sau đó có thể được truyền cho hàm bậc cao bằng cách truy cập phần tử ở vị trí 1 của bộ.
Ví dụ như sau:
numbers = [1, 2, 3, 4, 5]
# Lambda function with print to debug intermediate values
filtered_numbers = filter(lambda x: (print(f'Checking: {x} -> {x >= 3}'), x >= 3)[1], numbers)
# Converting filter object to list to force evaluation
print(list(filtered_numbers))
# Checking: 1 -> False
# Checking: 2 -> False
# Checking: 3 -> True
# Checking: 4 -> True
# Checking: 5 -> True
# [3, 4, 5]
Trong đoạn mã này, một mẹo được dùng để in các bước trung gian khi lọc danh sách số. Hàm lambda trong filter bao gồm một bộ: phần tử đầu là câu lệnh print ghi lại số hiện tại và liệu nó có thỏa điều kiện (x >= 3) hay không, và phần tử thứ hai là chính điều kiện đó.
Ký hiệu [1] ở cuối lambda đảm bảo điều kiện (x >= 3) được trả về cho hàm filter đồng thời cho phép câu lệnh print chạy để gỡ lỗi.
Chuyển đối tượng filter thành danh sách buộc việc đánh giá tất cả phần tử, kích hoạt các câu lệnh print cho mỗi số. Cách tiếp cận này giúp gỡ lỗi logic trong khi vẫn giữ nguyên chức năng của phép lọc.
Thực hành tốt nhất khi dùng hàm Lambda
Thực hành tốt nhất khi dùng hàm lambda là hiểu khi nào nên dùng và khi nào nên tránh.
Khi nào nên dùng hàm Lambda
- Logic ngắn, đơn giản. Lý tưởng cho các thao tác ngắn gọn, không cần định nghĩa đầy đủ một hàm.
- Hàm bậc cao. Hoạt động hiệu quả khi làm đối số cho các hàm bậc cao như
map(),filter()hoặcsorted(). - Hàm tạm thời (dùng một lần). Hữu ích khi chỉ cần một hàm một lần và định nghĩa bằng
defsẽ làm mã rối thêm. - Cải thiện khả năng đọc. Phù hợp cho tác vụ đơn giản nơi việc dùng lambda giúp mã gọn và dễ theo dõi.
Khi nào nên tránh dùng hàm Lambda
- Logic phức tạp hoặc nhiều dòng. Lambda bị giới hạn ở một biểu thức và có thể nhanh chóng trở nên khó đọc với thao tác phức tạp.
- Hàm dùng lại hoặc cần đặt tên. Nếu hàm cần tái sử dụng hoặc hưởng lợi từ một tên mô tả, hàm
deftiêu chuẩn sẽ phù hợp hơn. - Gỡ lỗi hoặc tài liệu. Hàm lambda không thể bao gồm docstring và có thể khó gỡ lỗi hơn so với hàm có tên.
Để nâng cao khả năng đọc và bảo trì khi dùng lambda, hãy làm theo các thực hành tốt sau:
- Dùng tên biến có tính mô tả để rõ ràng.
- Giữ đơn giản: Lambda lý tưởng nên nằm trên một dòng và thể hiện logic thẳng thắn.
- Hạn chế lồng nhau: Tránh dùng hàm lambda bên trong các hàm lambda khác hoặc cấu trúc dữ liệu phức tạp trừ khi thực sự cần thiết.
- Ưu tiên khả năng đọc hơn độ ngắn gọn: Nếu dùng lambda làm giảm khả năng đọc, tốt hơn là định nghĩa một hàm có tên.
Kết luận
Hàm lambda trong Python là công cụ hữu hiệu để viết các hàm ẩn danh, ngắn gọn. Chúng phát huy tác dụng trong các tình huống cần thao tác ngắn, tạm thời hoặc nội tuyến, đặc biệt khi dùng với các hàm bậc cao như map, filter hoặc sorted.
Tuy nhiên, cần sử dụng một cách cân nhắc, vì logic phức tạp phù hợp hơn với các hàm tiêu chuẩn được định nghĩa bằng def. Bằng cách hiểu rõ điểm mạnh, hạn chế và thực hành tốt nhất, bạn có thể tận dụng hiệu quả hàm lambda để viết mã Python sạch, hiệu quả và dễ bảo trì.
Để tìm hiểu thêm về các hàm Python, hãy xem các tài nguyên của DataCamp.
Câu hỏi thường gặp về Hàm Lambda trong Python
Tại sao dùng hàm lambda?
Chúng rất phù hợp để đơn giản hóa các tác vụ ngắn hạn, tinh gọn mã với các hàm bậc cao như map, filter hoặc sorted, và giảm lộn xộn khi định nghĩa logic tạm thời hoặc dùng một lần.
Khi nào tôi nên dùng hàm lambda?
Hàm lambda phù hợp cho: logic ngắn, đơn giản, thích hợp viết một dòng; làm đối số cho các hàm bậc cao như map() hoặc filter(); và cho các hàm tạm thời chỉ cần dùng một lần.
Khi nào tôi nên tránh dùng hàm lambda?
Hàm lambda có thể không phải lựa chọn tốt nhất cho logic phức tạp hoặc các hàm cần tài liệu (như docstring).

Mark Pedigo, PhD, là một nhà khoa học dữ liệu xuất sắc với chuyên môn về khoa học dữ liệu trong y tế, lập trình và giáo dục. Với bằng Tiến sĩ Toán học, Cử nhân Khoa học Máy tính và Chứng chỉ Chuyên nghiệp về AI, Mark kết hợp hiểu biết kỹ thuật với khả năng giải quyết vấn đề thực tiễn. Sự nghiệp của anh bao gồm các vai trò trong phát hiện gian lận, dự đoán tử vong ở trẻ sơ sinh và dự báo tài chính, cùng với những đóng góp cho phần mềm ước tính chi phí của NASA. Là một nhà giáo dục, anh đã giảng dạy tại DataCamp và Đại học Washington ở St. Louis, đồng thời cố vấn cho các lập trình viên trẻ. Trong thời gian rảnh, Mark thích hoạt động ngoài trời ở Minnesota cùng vợ là Mandy và chú chó Harley, và chơi piano jazz.