Từ những hàm đơn giản đến công cụ mạnh mẽ
Bạn đã biết cách tạo hàm, truyền tham số, và trả về kết quả. Nhưng đó mới chỉ là phần nổi của tảng băng lập trình.
Trong bài học này, bạn sẽ tiếp cận những khái niệm giúp hàm trở nên linh hoạt, gọn nhẹ, và mạnh mẽ hơn nhiều:
- Làm sao để một hàm nhận được số lượng tham số không cố định?
- Làm sao để viết một hàm “siêu ngắn” chỉ trong 1 dòng?
- Và cuối cùng, làm sao để hàm gọi lại chính nó để giải bài toán lặp lại?
Chào mừng bạn đến với “hàm nâng cao” – trái tim của tư duy giải thuật và xây dựng công cụ linh hoạt.
Mục tiêu bài học
- Hiểu cách dùng
*args
và**kwargs
để truyền nhiều tham số - Biết viết hàm ẩn danh với
lambda
- Làm quen với đệ quy – một kỹ thuật cực kỳ quan trọng trong tư duy thuật toán
- Áp dụng vào các tình huống thực tế
*args
– Nhận nhiều đối số không cố định
Khi bạn không biết trước người dùng sẽ truyền bao nhiêu giá trị vào hàm, hãy dùng *args
.
def tinh_tong(*args):
return sum(args)
print(tinh_tong(1, 2, 3)) # 6
print(tinh_tong(10, 20, 30, 40)) # 100
*args
sẽ nhận các giá trị thành một tuple
**kwargs
– Nhận nhiều cặp key=value
Dùng khi muốn truyền nhiều tên tham số tùy ý.
def thong_tin(**kwargs):
for k, v in kwargs.items():
print(f"{k}: {v}")
thong_tin(ten="An", tuoi=20, que="Hà Nội")
**kwargs
sẽ nhận các đối số thành dictionary
lambda
– Hàm ẩn danh, viết trong 1 dòng
Cú pháp:
lambda tham_so: biểu_thức
Ví dụ:
tinh_binh_phuong = lambda x: x * x
print(tinh_binh_phuong(5)) # 25
Dùng lambda
khi:
- Viết hàm ngắn gọn
- Dùng tạm thời (không cần định nghĩa riêng)
- Thường dùng với các hàm như
map()
,filter()
,sorted()
…
Ví dụ: Dùng lambda để sắp xếp
ds = [(1, 'a'), (3, 'b'), (2, 'c')]
ds.sort(key=lambda x: x[0])
Đệ quy (recursion) – Khi hàm tự gọi lại chính nó
Khái niệm: Hàm đệ quy là hàm gọi lại chính nó để giải bài toán nhỏ hơn của chính nó.
Đây là tư duy lập trình rất mạnh, dùng trong các bài toán: chia để trị, cây nhị phân, tìm đường, tổ hợp, v.v.
Ví dụ 1: Giai thừa n! = n × (n-1)!
def giai_thua(n):
if n == 0 or n == 1:
return 1
return n * giai_thua(n - 1)
print(giai_thua(5)) # 120
Ví dụ 2: Dãy Fibonacci
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
for i in range(7):
print(fibonacci(i), end=" ")
So sánh: Hàm thường – lambda – đệ quy
Đặc điểm | Hàm thường | Lambda | Đệ quy |
---|---|---|---|
Nhiều dòng | Có | Không | Có |
Có tên riêng | Có | Thường là không | Có |
Gọi lại chính nó | Không | Không | Có |
Dùng trong | Mọi nơi | map , sorted | Bài toán lặp, cây |
Bài tập luyện tập
Bài 1: Viết hàm tong_chan(*args)
trả về tổng các số chẵn từ tham số truyền vào.
Bài 2: Viết hàm dùng **kwargs
để in hồ sơ học sinh (có thể có hoặc không các trường: tên, tuổi, lớp…).
Bài 3: Viết hàm lambda kiểm tra số chia hết cho 3 và 5.
Bài 4: Viết hàm đệ quy tính tổng từ 1 đến n.
Bài 5: Viết hàm đệ quy đảo ngược chuỗi: "abc"
→ "cba"
Kết luận
Bạn vừa bước sang một đẳng cấp mới trong tư duy viết hàm. Những kỹ thuật hôm nay sẽ giúp bạn xử lý mọi dạng dữ liệu đầu vào, tạo ra các công cụ linh hoạt, và giải quyết bài toán phức tạp bằng logic đơn giản hóa dần.
Bài tiếp theo: Bài 14 – Xử lý chuỗi nâng cao
Trong bài sắp tới, bạn sẽ khai thác sâu chuỗi ký tự: cắt, định dạng, tìm kiếm, thay thế – những thao tác không thể thiếu trong xử lý văn bản, dữ liệu từ file, hoặc nội dung nhập từ người dùng.
Thảo luận