6. Recursion vs. Iteration

2024. 3. 14. 01:14·Python

 

 

 
 

Recursion vs. Iteration¶

A recursive function is concptually clean.

 
In [1]:
def factorial(n):
    if n < 2:
        return 1
    return n * factorial(n - 1)

print(factorial(5))
 
 
120
 
 

However, it is relatively expensive because of the creation and manipulation of stack frames. You can visualize its execution here.

For better efficiency, we can convert the function to use iteration instead

Approach 1: Brute Force Using Stack¶

We can use a stack data structure to simulate the stack frames of the recursive call. This is tedious and not particularly efficient.

 
In [2]:
def factorial_stack(n):
    stack = []
    stack.append(n)
    state = 'Pre'

    while True:
        if state == 'Pre':
            if n > 2:
                n = n - 1
                stack.append(n)
            else:
                state = 'Post'
        else:
            result = stack.pop()
            if not stack:
                break
            n = stack.pop()
            stack.append(n * result)

    return result

print(factorial_stack(5))
 
 
120
 
 

Approach 2: Convert into Tail Calls¶

Step 1: Convert recursive calls into tail calls with return statement.

 
In [3]:
def factorial1a(n, acc=1):
    if n < 2:
        return 1 * acc
    return factorial1a(n - 1, acc * n)
    
print(factorial1a(5))
 
 
120
 
 

Step 2: Enclose function body in while True:

 
In [4]:
def factorial1b(n, acc=1):
    while True:
        if n < 2:
            return 1 * acc
        return factorial1a(n - 1, acc * n)

print(factorial1b(5))
 
 
120
 
 

Step 3: Replace all recursive tail calls f(x=x1, y=y1, ...) with x, y, ... = x1, y1, .... Be sure to update all arguments in the assignment.

 
In [5]:
def factorial1c(n, acc=1):
    while True:
        if n < 2:
            return 1 * acc
        n, acc = n - 1, acc * n

print(factorial1c(5))
 
 
120
 
 

Step 4: Clean up the code to make it more idiomatic.

 
In [6]:
def factorial1d(n):
    acc=1
    while n>1:
        n, acc = n - 1, acc * n
    return acc

print(factorial1d(5))
 
 
120
 
 

Now the stack size from is reduced from O(n) to O(1). You can visualize its execution here.

'Python' 카테고리의 다른 글

8. Text File I/O  (0) 2024.03.14
7. Lambda Functions  (0) 2024.03.14
5. Function  (0) 2024.03.14
4. Conditionals and Loops  (0) 2024.03.14
3. Exception Handling  (0) 2024.03.14
'Python' 카테고리의 다른 글
  • 8. Text File I/O
  • 7. Lambda Functions
  • 5. Function
  • 4. Conditionals and Loops
Juson
Juson
  • Juson
    Juson의 데이터 공부
    Juson
  • 전체
    오늘
    어제
    • 분류 전체보기 (95)
      • RAG (2)
      • AI (2)
        • NLP (0)
        • Generative Model (0)
        • Deep Reinforcement Learning (2)
        • LLM (0)
      • Logistic Optimization (0)
      • Machine Learning (37)
        • Linear Regression (2)
        • Logistic Regression (2)
        • Decision Tree (5)
        • Naive Bayes (1)
        • KNN (2)
        • SVM (2)
        • Clustering (4)
        • Dimension Reduction (3)
        • Boosting (6)
        • Abnomaly Detection (2)
        • Recommendation (4)
        • Embedding & NLP (4)
      • Reinforcement Learning (5)
      • Deep Learning (10)
        • Deep learning Bacis Mathema.. (10)
      • Optimization (2)
        • OR Optimization (0)
        • Convex Optimization (0)
        • Integer Optimization (0)
      • SNA 분석 (0)
      • 포트폴리오 최적화 공부 (0)
        • 최적화 기법 (0)
        • 금융 베이스 (0)
      • Finanancial engineering (0)
      • 프로그래머스 데브코스(Boot camp) (15)
        • SQL (9)
        • Python (5)
        • Machine Learning (1)
      • Python (22)
      • Project (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
Juson
6. Recursion vs. Iteration
상단으로

티스토리툴바