Câu 1Cái nào dưới đây là biểu thức lambda hợp lệ?
Biểu thức Lambda — Viết hàm vô danh trong một dòng
Học biểu thức lambda trong Python để viết hàm vô danh chỉ trong một dòng và kết hợp tự nhiên với các hàm bậc cao.
Trong bài trước về hàm bậc cao, bạn đã thấy cách truyền hàm như tham số và giá trị trả về. Định nghĩa một hàm mới bằng def mỗi khi cần truyền callback nghĩa là một thao tác một dòng đột nhiên mất 3 hay 4 dòng.
Đó là lúc biểu thức lambda (lambda) xuất hiện — chúng cho phép bạn viết một hàm vô danh trên một dòng duy nhất. Hoàn hảo cho những mảnh logic nhỏ không xứng đáng có cả một def.
Lambda là gì — So với def
Cú pháp là lambda args: biểu thức. Kết quả của biểu thức trở thành giá trị trả về trực tiếp, và bạn không viết return (thực ra, làm vậy sẽ kích hoạt SyntaxError).
Khác với hàm thông thường, lambda không có tên, nên không thể gọi trừ khi bạn gán nó vào biến. Tên biến bạn gán nó vào sẽ trở thành tên của hàm.
# Viết bằng def
def add_tax(price):
return int(price * 1.1)
print(add_tax(980)) # 1078
# Cùng logic dưới dạng lambda (không cần return)
add_tax = lambda price: int(price * 1.1)
print(add_tax(980)) # 1078
Chỉ cho phép biểu thức — Không có câu lệnh
Thân lambda chỉ chứa biểu thức (cái gì đó định trị thành một giá trị). Câu lệnh if, vòng lặp for, và phép gán (=) không vừa. Khoảnh khắc bạn muốn cái gì đó cầu kỳ hơn, quay lại def — đó là lựa chọn đúng.
Nhiều tham số, biểu thức điều kiện, và mặc định
Lambda cũng nhận nhiều tham số. Chỉ cần liệt kê chúng cách nhau bằng dấu phẩy, như lambda x, y: x * y.
Bạn cũng có thể dùng tham số mặc định giống như với def. Để đổi giá trị dựa trên điều kiện, đặt một biểu thức điều kiện value1 if condition else value2 vào thân.
# Nhiều tham số
rect_area = lambda width, height: width * height
print(rect_area(4, 5)) # 20
# Tham số mặc định (bỏ rate để dùng 0.1)
add_tax = lambda price, rate=0.1: int(price * (1 + rate))
print(add_tax(1000)) # 1100
print(add_tax(1000, 0.08)) # 1080
# Biểu thức điều kiện
judge_age = lambda age: "người lớn" if age >= 20 else "trẻ vị thành niên"
print(judge_age(25)) # người lớn
print(judge_age(17)) # trẻ vị thành niên
# Trả về nhiều giá trị dưới dạng tuple
stats = lambda x, y: (x + y, x * y)
print(stats(3, 4)) # (7, 12)
lambda xử lý nhiều tham số, tham số mặc định, và rẽ nhánh với biểu thức điều kiện với cảm giác giống def.Kết hợp với hàm bậc cao — Nơi Lambda tỏa sáng
Lambda thực sự kiếm được giá trị khi bạn muốn trao một hàm dùng-một-lần cho hàm bậc cao. Ví dụ, tham số key của sorted() là một hàm bậc cao nhận "một hàm trả về khóa sắp xếp từ mỗi phần tử."
Với một thứ tự sắp xếp bạn không cần đặt tên và dùng lại, viết key=lambda x: x["price"] inline tại chỗ gọi là dạng tự nhiên nhất.
products = [
{"name": "Vở", "price": 480},
{"name": "Bút", "price": 120},
{"name": "Tẩy", "price": 80},
]
# Sắp xếp theo giá tăng dần (truyền lambda inline làm key)
cheap_first = sorted(products, key=lambda item: item["price"])
for item in cheap_first:
print(item["name"], item["price"])
# Tẩy 80
# Bút 120
# Vở 480
# Cùng hàm bậc cao process_list có thể đổi hành vi qua lambda
def process_list(numbers, func):
for n in numbers:
print(func(n))
process_list([1, 2, 3, 4], lambda x: x ** 2)
# 1
# 4
# 9
# 16
Khi nào dùng Lambda — và khi nào tránh
Lambda tiện lợi, nhưng dùng chúng ở khắp nơi thực ra làm tổn hại tính dễ đọc. Bảng dưới tổng hợp: tìm đến lambda cho thao tác một lần, một dòng, và giữ def cho bất cứ thứ gì phức tạp hoặc dùng lại.
| Tình huống | Khuyến nghị | Lý do |
|---|---|---|
| Truyền cho key của sorted, filter, map | lambda | Một dòng truyền tải ý định; không cần đặt tên |
| Biểu thức một dòng như giá đã thuế | lambda | Hàm có tên ngắn không cần import |
| Logic cần if / for / try | def | lambda chỉ là biểu thức; câu lệnh phát sinh SyntaxError |
| Logic dùng lại từ nhiều nơi | def | Tên truyền tải ý định và hỗ trợ test, doc |
| Thân chạy 3+ dòng | def | Nhồi vào lambda chỉ làm tổn hại tính dễ đọc |
Đừng nhồi mọi thứ vào Lambda
Xếp ba biểu thức điều kiện lồng nhau hoặc nối vài lệnh gọi hàm với nhau và bạn rốt cuộc có code trên một dòng nhưng không đọc được. Khoảnh khắc bạn nghĩ "Tôi muốn để lại comment giải thích lambda này làm gì," hãy với tay tới def thay vào đó.
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2Code này in gì?f = lambda x, y=3: x ** y
print(f(2))
Câu 3Cái nào dưới đây là cách dùng phù hợp nhất của biểu thức lambda?