이제부터는 앞서 배운 함수를 어떻게 활용하는지에 대해서 공부합니다.
1. 재귀함수
재귀함수는 함수 내부에서 같은 기능을 사용하는 거예요.
재귀는 자기 자신을 호출한다는 의미를 가지고 있습니다.
가령 팩토리얼 이라는 연산자가 있는데 이것을 구하는 것으로 예제를 활용해볼게요.
팩토리얼은 n! 의 기호로 사용합니다.
n! = n * (n-1) * (n-2) * (n-3) ... * 1
이렇게 연산을 이어가는 것을 팩토리얼이라고 합니다.
ex) 5! = 5 * 4 * 3 * 2 * 1
이렇게 팩토리얼을 구현화할 때, 반복문으로 팩토리얼을 구하거나 재귀 함수로 팩토리얼을 구할 수 있습니다.
먼저 반복문으로 구해볼게요.
def factorial(n): -> factorial () 함수를 만들어줍니다.
output = 1 -> 팩토리얼은 곱셈이기 때문에 초기값은 0 이 아닌 1 이 됩니다.
for i in range(1, n+1): -> 범위는 (1부터 n번째가 되는데, 파이썬은 범위의 맨 마지막 인덱스는 세지 않으므로 +1 을 붙여줍니다.)
output *= i 그리고 나서 i의 값을 곱하고 그 값을 다시 i로 저장하는 식으로 반복해줍니다.
즉 range의 범위가 1에서 5까지라고 한다면 반복되면서 1 * (1+1) * (1+1+1) * (1+1+1+1) * (1+1+1+1+1)로 반복 됩니다.
1 * 2 * 3 * 4 * 5 로 반복되는 거예요.
return output -> 그 뒤에 output의 값을 출력하며 함수를 시작한 처음으로 돌아갑니다.
그럼 이제 재귀함수로 구해볼게요.
팩토리얼은 수식으로 표현하자면 다음과 같습니다. (물론 표현할 수 있는 방법은 무수히 많아요!)
factorial(n) = n * factorial(n-1) (n>= 1 일 때)
factorial(0) = 1
그럼 여기서 재귀 표현으로 팩토리얼을 계산하는 코딩을 해볼게요.
반복문을 사용하는 것보다 재귀 표현으로 사용하는 것이 코드가 더 짧아졌습니다.
하지만 재귀 함수는 상황에 따라서 기하급수 적으로 많이 반복할 수 있는 문제가 있으므로 사용할 때 유의해야해요.
재귀 함수를 하나 더 살펴보자면, 피보나치 수열이 있습니다.
이런 식으로 첫 번째와 두 번째 항은 반드시 1이고 그 뒤에는 앞의 항과 그 앞의 항을 더한 값이 되는 수열입니다.
1번째 수열 = 1
2번째 수열 = 2
n번째 수열 = (n-1)번째 수열 + (n-2)번째 수열
이를 코드로 구현해보면
def fibonacci(n):
if n == 1 :
return 1
if n == 2 :
return 2
else :
return fibonacci(n-1) + fibonacci(n-2)
가 되겠죠.
그런데 이것은 문제가 있습니다. 피보나치 수열을 구하는 n의 값에 35를 입력할 경우에 시간이 오래 걸립니다.
숫자가 그보다 더 늘어날 경우에는 60이라고 할 때에는 1시간이 훨씬 넘게 걸려요.
같은 것을 여러번 연산하기 때문에 시간이 오래 걸리는 거예요.
덧셈 횟수가 기하급수적으로 늘어나기 때문에 계산에 시간이 오래 걸립니다.
예를 들어 35번째 피보나치 수를 구할 때에는 덧셈을 18454929번 반복해요.
이러한 문제로 인해 재귀함수를 사용할 때에는 메모화를 통해 코드를 간결하고 빠르게 실행합니다.
값을 새로 계산하는 것이 아니라 값을 메모해두었다가 그것을 불러오는 방식이에요.
값을 저장해두는 곳은 딕셔너리입니다.
직접 확인해볼게요.
재귀함수는 조심해서 써야겠어요..
2. 리스트 평탄화하는 재귀함수
리스트 평탄화는 중첩된 리스트가 있을 때 중첩을 모두 제거하고 풀어서 1차원 리스트를 만드는 것입니다.
가령 2차원의 리스트가 있다면 (리스트 안에 리스트가 있는 리스트) 이것을 평탄화 시키는 방법은 편합니다.
값은 요로케 나와요
하지만 여기서 단점은 3차원의 리스트가 된다면 같은 과정을 여러번 반복해서 리스트를 평탄화 해야한다는 거예요.
그래서 이럴 때 재귀함수를 쓰면 편리하게 평탄화를 할 수 있습니다.
'파이썬 > 파이썬 입문 공부일지' 카테고리의 다른 글
파이썬 공부일지 20. 파일처리! (0) | 2022.10.19 |
---|---|
파이썬 공부일지 19. 함수 활용 (튜플, 람다)! (0) | 2022.10.18 |
파이썬 공부일지 17. 함수 만들기! (0) | 2022.10.14 |
파이썬 공부일지 16. 범위 자료형 range, 조건반복문 while! (1) | 2022.10.13 |
파이썬 공부일지 15. 딕셔너리! (1) | 2022.10.13 |