Đăng nhập

Bài 13: Hàm nâng cao – *args, **kwargs, lambda, và đệ quy

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**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ểmHàm thườngLambdaĐệ quy
Nhiều dòngKhông
Có tên riêngThường là không
Gọi lại chính nóKhôngKhông
Dùng trongMọi nơimap, sortedBà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

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Đăng ký nhận tin mới

Nhận bài học, tài nguyên và cơ hội việc làm qua email hàng tuần.

Chúng tôi cam kết không spam. Bạn có thể hủy bất cứ lúc nào.