Hướng dẫn how return works python recursion? - cách trả về hoạt động đệ quy python?

Trong hướng dẫn này, bạn sẽ học cách tạo một hàm đệ quy (một hàm tự gọi).

Show

Đệ quy là gì?

Đệ quy là quá trình xác định một cái gì đó theo chính nó.

Một ví dụ thế giới vật lý sẽ là đặt hai gương song song đối diện nhau. Bất kỳ đối tượng ở giữa chúng sẽ được phản ánh đệ quy.


Chức năng đệ quy Python

Trong Python, chúng ta biết rằng một hàm có thể gọi các chức năng khác. Thậm chí có thể cho chức năng gọi chính nó. Các loại cấu trúc này được gọi là các hàm đệ quy.

Hình ảnh sau đây cho thấy hoạt động của một hàm đệ quy gọi là

def recursor():
    recursor()
recursor()
0.

Hướng dẫn how return works python recursion? - cách trả về hoạt động đệ quy python?
Chức năng đệ quy trong Python

Sau đây là một ví dụ về hàm đệ quy để tìm giai thừa của một số nguyên.

Factorial của một số là sản phẩm của tất cả các số nguyên từ 1 đến số đó. Ví dụ: giai thừa của 6 (ký hiệu là 6!) Là 1*2*3*4*5*6 = 720.

Ví dụ về hàm đệ quy

def factorial(x):
    """This is a recursive function
    to find the factorial of an integer"""

    if x == 1:
        return 1
    else:
        return (x * factorial(x-1))


num = 3
print("The factorial of", num, "is", factorial(num))

Đầu ra

The factorial of 3 is 6

Trong ví dụ trên,

def recursor():
    recursor()
recursor()
1 là một hàm đệ quy như nó tự gọi.

Khi chúng ta gọi hàm này với số nguyên dương, nó sẽ tự gọi mình bằng cách giảm số.

Mỗi hàm nhân số số với giai thừa của số bên dưới nó cho đến khi nó bằng một. Cuộc gọi đệ quy này có thể được giải thích trong các bước sau.

factorial(3)          # 1st call with 3
3 * factorial(2)      # 2nd call with 2
3 * 2 * factorial(1)  # 3rd call with 1
3 * 2 * 1             # return from 3rd call as number=1
3 * 2                 # return from 2nd call
6                     # return from 1st call

Chúng ta hãy xem một hình ảnh hiển thị một quá trình từng bước về những gì đang diễn ra:

Hướng dẫn how return works python recursion? - cách trả về hoạt động đệ quy python?
Làm việc của một chức năng giai thừa đệ quy

Đệ quy của chúng tôi kết thúc khi số lượng giảm xuống 1. cái này được gọi là điều kiện cơ sở.

Mỗi chức năng đệ quy phải có một điều kiện cơ sở dừng đệ quy hoặc nếu không thì hàm tự gọi chính nó.

Thông dịch viên Python giới hạn độ sâu của đệ quy để giúp tránh các đệ quy vô hạn, dẫn đến tràn chồng.

Theo mặc định, độ sâu tối đa của đệ quy là 1000. Nếu giới hạn được vượt qua, nó sẽ dẫn đến

def recursor():
    recursor()
recursor()
2. Hãy nhìn vào một điều kiện như vậy.

def recursor():
    recursor()
recursor()

Đầu ra

Traceback (most recent call last):
  File "<string>", line 3, in <module>
  File "<string>", line 2, in a
  File "<string>", line 2, in a
  File "<string>", line 2, in a
  [Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded

Trong ví dụ trên, def recursor(): recursor() recursor()1 là một hàm đệ quy như nó tự gọi.

  1. Khi chúng ta gọi hàm này với số nguyên dương, nó sẽ tự gọi mình bằng cách giảm số.
  2. Mỗi hàm nhân số số với giai thừa của số bên dưới nó cho đến khi nó bằng một. Cuộc gọi đệ quy này có thể được giải thích trong các bước sau.
  3. Chúng ta hãy xem một hình ảnh hiển thị một quá trình từng bước về những gì đang diễn ra:

Làm việc của một chức năng giai thừa đệ quy

  1. Đệ quy của chúng tôi kết thúc khi số lượng giảm xuống 1. cái này được gọi là điều kiện cơ sở.
  2. Mỗi chức năng đệ quy phải có một điều kiện cơ sở dừng đệ quy hoặc nếu không thì hàm tự gọi chính nó.
  3. Thông dịch viên Python giới hạn độ sâu của đệ quy để giúp tránh các đệ quy vô hạn, dẫn đến tràn chồng.

Xem bây giờ hướng dẫn này có một khóa học video liên quan được tạo bởi nhóm Python thực sự. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn về sự hiểu biết của bạn: Suy nghĩ đệ quy trong Python This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Thinking Recursively in Python

Làm thế nào để trả lại hoạt động trong đệ quy?

Với đệ quy, chúng tôi đang chờ các giá trị trả về đến từ các bối cảnh thực thi khác. Những bối cảnh khác cao hơn lên ngăn xếp. Khi mục cuối cùng trên ngăn xếp hoàn thành thực thi, bối cảnh đó sẽ tạo ra giá trị trả về. Giá trị trả về này được truyền xuống dưới dạng giá trị trả về từ trường hợp đệ quy sang mục tiếp theo.

Hướng dẫn how return works python recursion? - cách trả về hoạt động đệ quy python?
Một tuyên bố trả lại có dừng lại không?

Một tuyên bố trả lại sẽ không dừng tất cả các cuộc gọi đệ quy trước được thực hiện.

Hàm trả về làm gì trong Python?

Kính gửi ông già Noel Pythonic

Tôi nhận ra rằng là đồng nghiệp Pythonistas, tất cả chúng ta đều đồng ý với người lớn ở đây, nhưng trẻ em dường như rình mò vẻ đẹp của đệ quy tốt hơn. Vì vậy, hãy để Lôi không phải là người lớn ở đây trong một khoảnh khắc và nói về cách chúng ta có thể sử dụng đệ quy để giúp ông già Noel.

Bạn đã bao giờ tự hỏi làm thế nào những món quà Giáng sinh được giao? Tôi chắc chắn có, và tôi tin rằng Santa Claus có một danh sách những ngôi nhà mà anh ấy vượt qua. Anh ta đi đến một ngôi nhà, bỏ quà, ăn bánh quy và sữa, và chuyển sang ngôi nhà bên cạnh trong danh sách. Vì thuật toán này để cung cấp các món quà dựa trên một cấu trúc vòng lặp rõ ràng, nó được gọi là một thuật toán lặp.

Hướng dẫn how return works python recursion? - cách trả về hoạt động đệ quy python?

Thuật toán phân phối hiện tại lặp được thực hiện trong Python:

houses = ["Eric's house", "Kenny's house", "Kyle's house", "Stan's house"]

def deliver_presents_iteratively():
    for house in houses:
        print("Delivering presents to", house)

>>>

>>> deliver_presents_iteratively()
Delivering presents to Eric's house
Delivering presents to Kenny's house
Delivering presents to Kyle's house
Delivering presents to Stan's house

Nhưng tôi cảm thấy cho ông già Noel. Ở tuổi của anh ấy, anh ấy không nên tự mình giao tất cả những món quà. Tôi đề xuất một thuật toán mà anh ta có thể chia công việc cung cấp quà tặng giữa các yêu tinh của mình:

  1. Bổ nhiệm một yêu tinh và đưa tất cả công việc cho anh ta
  2. Gán tiêu đề và trách nhiệm cho các yêu tinh dựa trên số lượng nhà mà họ chịu trách nhiệm:
    • def recursor():
          recursor()
      recursor()
      3 Anh ấy là người quản lý và có thể bổ nhiệm hai yêu tinh và chia công việc của mình cho họ
    • def recursor():
          recursor()
      recursor()
      4 Anh ấy là một công nhân và phải giao quà cho ngôi nhà được giao cho anh ấy
Hướng dẫn how return works python recursion? - cách trả về hoạt động đệ quy python?

Đây là cấu trúc điển hình của một thuật toán đệ quy. Nếu vấn đề hiện tại đại diện cho một trường hợp đơn giản, hãy giải quyết nó. Nếu không, chia nó thành các vấn đề phụ và áp dụng cùng một chiến lược cho chúng.

Thuật toán phân phối hiện tại đệ quy được thực hiện trong Python:

houses = ["Eric's house", "Kenny's house", "Kyle's house", "Stan's house"]

# Each function call represents an elf doing his work 
def deliver_presents_recursively(houses):
    # Worker elf doing his work
    if len(houses) == 1:
        house = houses[0]
        print("Delivering presents to", house)

    # Manager elf doing his work
    else:
        mid = len(houses) // 2
        first_half = houses[:mid]
        second_half = houses[mid:]

        # Divides his work among two elves
        deliver_presents_recursively(first_half)
        deliver_presents_recursively(second_half)

>>>

>>> deliver_presents_recursively(houses)
Delivering presents to Eric's house
Delivering presents to Kenny's house
Delivering presents to Kyle's house
Delivering presents to Stan's house

Nhưng tôi cảm thấy cho ông già Noel. Ở tuổi của anh ấy, anh ấy không nên tự mình giao tất cả những món quà. Tôi đề xuất một thuật toán mà anh ta có thể chia công việc cung cấp quà tặng giữa các yêu tinh của mình:

Bổ nhiệm một yêu tinh và đưa tất cả công việc cho anh ta

Gán tiêu đề và trách nhiệm cho các yêu tinh dựa trên số lượng nhà mà họ chịu trách nhiệm:

def recursor():
    recursor()
recursor()
3 Anh ấy là người quản lý và có thể bổ nhiệm hai yêu tinh và chia công việc của mình cho họ

  1. def recursor():
        recursor()
    recursor()
    4 Anh ấy là một công nhân và phải giao quà cho ngôi nhà được giao cho anh ấy

    Đây là cấu trúc điển hình của một thuật toán đệ quy. Nếu vấn đề hiện tại đại diện cho một trường hợp đơn giản, hãy giải quyết nó. Nếu không, chia nó thành các vấn đề phụ và áp dụng cùng một chiến lược cho chúng.

  2. Thuật toán phân phối hiện tại đệ quy được thực hiện trong Python:

    The factorial of 3 is 6
    0

Các chức năng đệ quy trong Python

Bây giờ chúng ta có một số trực giác về đệ quy, hãy để giới thiệu định nghĩa chính thức của một hàm đệ quy. Một hàm đệ quy là một hàm được xác định theo bản thân thông qua các biểu thức tự tham chiếu.

The factorial of 3 is 6
1

>>>

The factorial of 3 is 6
2

Nhưng tôi cảm thấy cho ông già Noel. Ở tuổi của anh ấy, anh ấy không nên tự mình giao tất cả những món quà. Tôi đề xuất một thuật toán mà anh ta có thể chia công việc cung cấp quà tặng giữa các yêu tinh của mình:

Hướng dẫn how return works python recursion? - cách trả về hoạt động đệ quy python?

Bổ nhiệm một yêu tinh và đưa tất cả công việc cho anh ta

Gán tiêu đề và trách nhiệm cho các yêu tinh dựa trên số lượng nhà mà họ chịu trách nhiệm:

  • def recursor():
        recursor()
    recursor()
    3 Anh ấy là người quản lý và có thể bổ nhiệm hai yêu tinh và chia công việc của mình cho họ
  • def recursor():
        recursor()
    recursor()
    4 Anh ấy là một công nhân và phải giao quà cho ngôi nhà được giao cho anh ấy

Đây là cấu trúc điển hình của một thuật toán đệ quy. Nếu vấn đề hiện tại đại diện cho một trường hợp đơn giản, hãy giải quyết nó. Nếu không, chia nó thành các vấn đề phụ và áp dụng cùng một chiến lược cho chúng.

Thuật toán phân phối hiện tại đệ quy được thực hiện trong Python:

The factorial of 3 is 6
3

>>>

The factorial of 3 is 6
4

Hướng dẫn how return works python recursion? - cách trả về hoạt động đệ quy python?

Nhưng tôi cảm thấy cho ông già Noel. Ở tuổi của anh ấy, anh ấy không nên tự mình giao tất cả những món quà. Tôi đề xuất một thuật toán mà anh ta có thể chia công việc cung cấp quà tặng giữa các yêu tinh của mình:

The factorial of 3 is 6
5

>>>

The factorial of 3 is 6
6

Nhưng tôi cảm thấy cho ông già Noel. Ở tuổi của anh ấy, anh ấy không nên tự mình giao tất cả những món quà. Tôi đề xuất một thuật toán mà anh ta có thể chia công việc cung cấp quà tặng giữa các yêu tinh của mình:

Bổ nhiệm một yêu tinh và đưa tất cả công việc cho anh ta

Gán tiêu đề và trách nhiệm cho các yêu tinh dựa trên số lượng nhà mà họ chịu trách nhiệm:

The factorial of 3 is 6
7

def recursor():
    recursor()
recursor()
3 Anh ấy là người quản lý và có thể bổ nhiệm hai yêu tinh và chia công việc của mình cho họ

The factorial of 3 is 6
8

Hướng dẫn how return works python recursion? - cách trả về hoạt động đệ quy python?
  1. def recursor():
        recursor()
    recursor()
    4 Anh ấy là một công nhân và phải giao quà cho ngôi nhà được giao cho anh ấy

    The factorial of 3 is 6
    9

  2. Đây là cấu trúc điển hình của một thuật toán đệ quy. Nếu vấn đề hiện tại đại diện cho một trường hợp đơn giản, hãy giải quyết nó. Nếu không, chia nó thành các vấn đề phụ và áp dụng cùng một chiến lược cho chúng.

Danh sách không phải là cấu trúc dữ liệu đệ quy duy nhất. Các ví dụ khác bao gồm đặt, cây, từ điển, v.v.

Cấu trúc dữ liệu đệ quy và các chức năng đệ quy đi cùng nhau như bánh mì và bơ. Cấu trúc chức năng đệ quy thường có thể được mô hình hóa theo định nghĩa của cấu trúc dữ liệu đệ quy mà nó lấy làm đầu vào. Hãy để tôi chứng minh điều này bằng cách tính tổng của tất cả các yếu tố của danh sách một cách đệ quy:

factorial(3)          # 1st call with 3
3 * factorial(2)      # 2nd call with 2
3 * 2 * factorial(1)  # 3rd call with 1
3 * 2 * 1             # return from 3rd call as number=1
3 * 2                 # return from 2nd call
6                     # return from 1st call
0

>>>

factorial(3)          # 1st call with 3
3 * factorial(2)      # 2nd call with 2
3 * 2 * factorial(1)  # 3rd call with 1
3 * 2 * 1             # return from 3rd call as number=1
3 * 2                 # return from 2nd call
6                     # return from 1st call
1

Đệ quy ngây thơ là ngây thơ

Các số Fibonacci ban đầu được định nghĩa bởi nhà toán học người Ý Fibonacci trong thế kỷ thứ mười ba để mô hình hóa sự phát triển của quần thể thỏ. Fibonacci phỏng đoán rằng số lượng con thỏ sinh ra trong một năm nhất định bằng với số lượng con thỏ được sinh ra ở mỗi năm trước, bắt đầu từ một cặp thỏ trong năm đầu tiên.

Để đếm số lượng thỏ được sinh ra vào năm thứ n, ông đã xác định mối quan hệ tái phát:

factorial(3)          # 1st call with 3
3 * factorial(2)      # 2nd call with 2
3 * 2 * factorial(1)  # 3rd call with 1
3 * 2 * 1             # return from 3rd call as number=1
3 * 2                 # return from 2nd call
6                     # return from 1st call
2

Các trường hợp cơ sở là:

factorial(3)          # 1st call with 3
3 * factorial(2)      # 2nd call with 2
3 * 2 * factorial(1)  # 3rd call with 1
3 * 2 * 1             # return from 3rd call as number=1
3 * 2                 # return from 2nd call
6                     # return from 1st call
3

Hãy để viết một chức năng đệ quy để tính toán số Fibonacci thứ n:

factorial(3)          # 1st call with 3
3 * factorial(2)      # 2nd call with 2
3 * 2 * factorial(1)  # 3rd call with 1
3 * 2 * 1             # return from 3rd call as number=1
3 * 2                 # return from 2nd call
6                     # return from 1st call
4

>>>

factorial(3)          # 1st call with 3
3 * factorial(2)      # 2nd call with 2
3 * 2 * factorial(1)  # 3rd call with 1
3 * 2 * 1             # return from 3rd call as number=1
3 * 2                 # return from 2nd call
6                     # return from 1st call
5

Đệ quy ngây thơ là ngây thơ

factorial(3)          # 1st call with 3
3 * factorial(2)      # 2nd call with 2
3 * 2 * factorial(1)  # 3rd call with 1
3 * 2 * 1             # return from 3rd call as number=1
3 * 2                 # return from 2nd call
6                     # return from 1st call
6

>>>

factorial(3)          # 1st call with 3
3 * factorial(2)      # 2nd call with 2
3 * 2 * factorial(1)  # 3rd call with 1
3 * 2 * 1             # return from 3rd call as number=1
3 * 2                 # return from 2nd call
6                     # return from 1st call
7

Đệ quy ngây thơ là ngây thơ

Các số Fibonacci ban đầu được định nghĩa bởi nhà toán học người Ý Fibonacci trong thế kỷ thứ mười ba để mô hình hóa sự phát triển của quần thể thỏ. Fibonacci phỏng đoán rằng số lượng con thỏ sinh ra trong một năm nhất định bằng với số lượng con thỏ được sinh ra ở mỗi năm trước, bắt đầu từ một cặp thỏ trong năm đầu tiên.

Để đếm số lượng thỏ được sinh ra vào năm thứ n, ông đã xác định mối quan hệ tái phát:

>>>

factorial(3)          # 1st call with 3
3 * factorial(2)      # 2nd call with 2
3 * 2 * factorial(1)  # 3rd call with 1
3 * 2 * 1             # return from 3rd call as number=1
3 * 2                 # return from 2nd call
6                     # return from 1st call
8

Đệ quy ngây thơ là ngây thơ

Các số Fibonacci ban đầu được định nghĩa bởi nhà toán học người Ý Fibonacci trong thế kỷ thứ mười ba để mô hình hóa sự phát triển của quần thể thỏ. Fibonacci phỏng đoán rằng số lượng con thỏ sinh ra trong một năm nhất định bằng với số lượng con thỏ được sinh ra ở mỗi năm trước, bắt đầu từ một cặp thỏ trong năm đầu tiên.

>>>

factorial(3)          # 1st call with 3
3 * factorial(2)      # 2nd call with 2
3 * 2 * factorial(1)  # 3rd call with 1
3 * 2 * 1             # return from 3rd call as number=1
3 * 2                 # return from 2nd call
6                     # return from 1st call
9

Đệ quy ngây thơ là ngây thơ

Các số Fibonacci ban đầu được định nghĩa bởi nhà toán học người Ý Fibonacci trong thế kỷ thứ mười ba để mô hình hóa sự phát triển của quần thể thỏ. Fibonacci phỏng đoán rằng số lượng con thỏ sinh ra trong một năm nhất định bằng với số lượng con thỏ được sinh ra ở mỗi năm trước, bắt đầu từ một cặp thỏ trong năm đầu tiên.

Để đếm số lượng thỏ được sinh ra vào năm thứ n, ông đã xác định mối quan hệ tái phát:

Các trường hợp cơ sở là:

  1. Hãy để viết một chức năng đệ quy để tính toán số Fibonacci thứ n:
  2. Tranh tính sau khi định nghĩa đệ quy của số Fibonacci thứ n khá không hiệu quả. Như bạn có thể thấy từ đầu ra ở trên, chúng tôi được tính toán lại các giá trị không cần thiết. Hãy cùng cố gắng cải thiện
    Traceback (most recent call last):
      File "<string>", line 3, in <module>
      File "<string>", line 2, in a
      File "<string>", line 2, in a
      File "<string>", line 2, in a
      [Previous line repeated 996 more times]
    RecursionError: maximum recursion depth exceeded
    5 bằng cách lưu trữ kết quả của mỗi tính toán FIBONACCI FK:
  3. Traceback (most recent call last):
      File "<string>", line 3, in <module>
      File "<string>", line 2, in a
      File "<string>", line 2, in a
      File "<string>", line 2, in a
      [Previous line repeated 996 more times]
    RecursionError: maximum recursion depth exceeded
    6 là một người trang trí lưu trữ kết quả. Do đó, chúng tôi tránh được tính toán lại bằng cách kiểm tra rõ ràng giá trị trước khi cố gắng tính toán nó. Một điều cần lưu ý về
    Traceback (most recent call last):
      File "<string>", line 3, in <module>
      File "<string>", line 2, in a
      File "<string>", line 2, in a
      File "<string>", line 2, in a
      [Previous line repeated 996 more times]
    RecursionError: maximum recursion depth exceeded
    6 là vì nó sử dụng từ điển để kết quả bộ đệm, các đối số từ khóa và vị trí (đóng vai trò là khóa trong từ điển đó) cho hàm phải được băm.
  4. Chi tiết phiền phức
  5. Python không có hỗ trợ cho việc loại bỏ cuộc gọi đuôi. Kết quả là, bạn có thể gây ra tràn ngăn xếp nếu cuối cùng bạn sử dụng nhiều khung ngăn xếp hơn độ sâu ngăn xếp cuộc gọi mặc định:

Hãy ghi nhớ giới hạn này nếu bạn có một chương trình yêu cầu đệ quy sâu. This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Thinking Recursively in Python

Làm thế nào để trả lại hoạt động trong đệ quy?

Với đệ quy, chúng tôi đang chờ các giá trị trả về đến từ các bối cảnh thực thi khác.Những bối cảnh khác cao hơn lên ngăn xếp.Khi mục cuối cùng trên ngăn xếp hoàn thành thực thi, bối cảnh đó sẽ tạo ra giá trị trả về. Giá trị trả về này được truyền xuống dưới dạng giá trị trả về từ trường hợp đệ quy sang mục tiếp theo.When the last item on the stack finishes execution, that context generates a return value. This return value gets passed down as a return value from the recursive case to the next item.

Một tuyên bố trả lại có dừng lại không?

Một tuyên bố trả lại sẽ không dừng tất cả các cuộc gọi đệ quy trước được thực hiện..

Hàm trả về làm gì trong Python?

Câu lệnh Python Return là một thành phần chính của các hàm và phương thức.Bạn có thể sử dụng câu lệnh trả về để làm cho các chức năng của bạn gửi các đối tượng Python trở lại mã người gọi.Các đối tượng này được gọi là giá trị trả về của hàm.Bạn có thể sử dụng chúng để thực hiện tính toán thêm trong các chương trình của bạn.make your functions send Python objects back to the caller code. These objects are known as the function's return value. You can use them to perform further computation in your programs.

Sự trở lại có cần thiết trong đệ quy không?

Nó không hoàn toàn cần thiết với các tuyên bố hoàn trả chỉ để đạt được đệ quy. either.