Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Đệ quy (Recursion) trong Python: Hướng dẫn

Cách dùng đệ quy trong Python

Đệ quy Python là chủ đề đáng sợ cho người mới. Hãy xóa bỏ mिथ rằng đệ quy khó bằng cách định nghĩa nó. Đệ quy là phương pháp lập trình nơi một hàm gọi chính nó.

Nghe đơn giản phải không? Khi nắm được, đệ quy không phải khái niệm khó.

Trong hướng dẫn Python này, chúng ta sẽ nói về đệ quy và cách hoạt động. Chúng ta sẽ đi qua ví dụ đệ quy dùng hàm giai thừa để giúp bạn bắt đầu phương pháp lập trình này.

Đệ quy là gì?

Đệ quy là định nghĩa cái gì đó dựa trên chính nó.

Hàm đệ quy giải quyết vấn đề bằng cách gọi chính nó lặp lại. Hành vi này được hỗ trợ trong hầu hết ngôn ngữ lập trình chính, như Python. Chúng là phần quan trọng của khoa học máy tính và khoa học dữ liệu.

Đệ quy hữu ích khi giải pháp vấn đề tìm thấy bằng cách chia nhỏ thành các vấn đề nhỏ hơn dùng cùng công thức. Các loại vấn đề này thường gọi là "thuật toán đệ quy". Chìa khóa giải quyết chúng nằm trong tên!

Lặp (Iterative) vs Đệ quy (Recursive)

Có hai cách giải thuật toán: lặp hoặc đệ quy.

Giải pháp lặp cho thuật toán được xem là "mạnh nhưng xấu". Chúng hoàn thành việc, nhưng không nhất thiết cách thanh lịch nhất. Để hiểu đúng thuật toán đệ quy, cần xem hàm lặp.

81% người tham gia cho biết họ cảm thấy tự tin hơn về cơ hội việc làm công nghệ sau khi tham gia bootcamp. Được ghép nối với bootcamp ngay hôm nay.

Sinh viên trung bình tốt nghiệp bootcamp mất chưa đến sáu tháng để chuyển đổi nghề nghiệp, từ khi bắt đầu bootcamp đến khi tìm được việc đầu tiên.

Hàm lặp là hàm giải quyết vấn đề dùng vòng lặp. Nó thực thi mã trong vòng lặp cho đến khi vòng lặp hoàn tất. Hàm đệ quy là hàm chia vấn đề thành phần nhỏ và giải quyết mỗi phần bằng cách gọi chính nó.

Giai thừa: Ví dụ lặp

Giai thừa là cách tốt chứng minh đệ quy và tư duy lặp. Trong toán, giai thừa là tổng một số và mọi số trước nó nhân cùng nhau.

Giai thừa 5 bằng 5 * 4 * 3 * 2 * 1. Giai thừa 2 bằng 2 * 1.

Để tính giai thừa, viết hàm lặp:

def factorial(number): total = 1 for n in range(1, number + 1): total = total * n return total

Hàm này dùng vòng for lặp qua tất cả số trong phạm vi 1 và số chỉ định cộng 1. Mỗi lần lặp, số vòng lặp đang lặp nhân với tổng. Hãy gọi hàm tìm giai thừa:

answer = factorial(4) print(answer)

Mã trả về: 24. Để đạt giải pháp, mã chạy:

  • 1 * 1 = 1
  • 2 * 2 = 4
  • 4 * 3 = 8
  • 8 * 4 = 24

Như bạn thấy, mã nhân 4 với tất cả số nhỏ hơn nó và chính nó.

Mã này hoạt động. Nhược điểm duy nhất là không thanh lịch như có thể. Đó là lúc hàm đệ quy hữu ích.

Giai thừa: Ví dụ đệ quy

Hãy viết hàm đệ quy tính giai thừa. Mở file Python mới và dán mã:

def factorial(number): if number == 1: return 1 else: return (number * factorial(number - 1))

Mã này dùng cách đệ quy. Khi hàm chạy, câu lệnh "if" thực thi. Câu lệnh kiểm tra số truyền vào hàm có bằng 1 không. Nếu có, hàm trả về 1. Ngược lại, giai thừa số được tính.

Tính toán nhân số truyền vào hàm với giai thừa số trước. Hàm gọi lại cho đến "number" bằng 1. Mỗi lần gọi, giá trị "number" giảm 1.

Hãy thử mã với số 4:

answer = factorial(4) print(answer)

Đáp án 24 trả về. Đáp án đúng; giống ví dụ trước. Chúng ta tìm giải pháp đệ quy thay vì lặp.

Vẫn cần giúp thêm? Hãy đi qua ví dụ đệ quy khác.

Đệ quy với dãy Fibonacci

Dãy fibonacci là chuỗi toán học mỗi số là tổng hai số trước. Dãy bắt đầu: 0, 1, 1, 2, 3, 5, 8, 13, v.v.

Dãy này cộng hai số tìm số tiếp theo. Làm cho nó lý tưởng cho đệ quy.

Mở file Python và dán mã:

def fibonacci(number): if number <= 1: return number else: return(fibonacci(number - 1) + fibonacci(number - 2))

Mã này tính tổng hai số trước trong danh sách, miễn "number" lớn hơn 1. Ngược lại, "number is returned". Bây giờ, gọi hàm:

executions = 5 print("Fibonacci Sequence:") for number in range(executions): print(fibonacci(number))

Biến executions theo dõi số lượng số trong dãy fibonacci muốn tính. Dùng tạo vòng for gọi hàm fibonacci() cho mỗi số trong phạm vi 1 và "executions".

Trước vòng for, in "Fibonacci Sequence:" ra console. Trong ví dụ này, vòng "for" thực thi:

fibonacci(1) fibonacci(2) fibonacci(3) fibonacci(4) fibonacci(5)

Hãy chạy mã cùng nhau xem:

Fibonacci Sequence: 0 1 1 2 3

Mã tính năm số đầu dãy fibonacci. Có thể tính thêm bằng cách tăng "executions".

Độ sâu đệ quy và điều kiện cơ sở (Base Conditions)

Hàm đệ quy phải có điều kiện cơ sở. Là điều kiện dừng đệ quy khi trường hợp cơ sở đáp ứng. Không có hàm cơ sở, vòng lặp vô hạn tạo ra.

Hàm đệ quy mặc định tự thực thi tối đa 1,000 lần. Khi đạt giới hạn, lỗi xuất hiện:

RecursionError: maximum recursion depth exceeded

Đây là điều kiện cơ sở cho chương trình fibonacci:

... if number <= 1: return number …

Điều kiện kiểm tra giá trị "number" trong chương trình fibonacci có bằng hoặc nhỏ hơn 1. Nếu có, giá trị "number" trả về; ngược lại, hàm đệ quy bắt đầu.

Tại sao dùng đệ quy?

Ưu điểm đệ quy so với hàm lặp? Kỹ thuật, cả hai đạt cùng kết quả. Lợi ích đệ quy là dễ đọc hơn.

Khi thấy hàm đệ quy, rõ ràng giải pháp vấn đề nằm ở chia nhỏ thành các phần. Mặc dù vòng lặp lặp đôi khi nhanh hơn, hàm đệ quy thường ưu tiên do dễ đọc.

Vì hàm đệ quy dễ đọc, chúng cũng dễ bảo trì và gỡ lỗi. Đặc biệt hữu ích khi viết thuật toán phức tạp khó hiểu.

Kết luận

Hàm đệ quy là hàm gọi chính nó tìm giải pháp vấn đề. 

Hàm đệ quy chia vấn đề thành nhiều phần và giải quyết một phần mỗi lần lặp. Hàm đệ quy thường dùng tính giai thừa và số trong dãy fibonacci. Chúng cũng dùng trong nhiều thuật toán.

Bây giờ bạn đã sẵn sàng làm việc với hàm đệ quy trong Python.