정처기 감자정처기 감자
Python함수/클래스

검색

검색어를 입력해 개념, 문제, 필기를 찾습니다.

Python 재귀 함수 (Recursion)

코딩Python
읽는데 12분 소요
처음 쓰인 날: 2026-04-10
마지막 수정일: 2026-09-29
조회수: —
선수학습(1개)
  • 함수의 기초

요약

Python 재귀 함수의 개념과 동작 원리를 알아봅니다. 기저 조건, 함수 호출 체인, 팩토리얼, 피보나치, 중첩 리스트 평탄화, 다중 재귀 등 정보처리기사 실기에 출제되는 재귀 개념을 정리합니다.

재귀 함수 핵심 정리

함수와 조건문을 먼저 알고 오면 이해가 쉽습니다. 아래는 이 페이지에서 배울 내용을 미리 정리한 표입니다.

개념설명예시
재귀 함수함수가 자기 자신을 호출하는 함수함수 f 안에서 f를 다시 부름
기저 조건재귀 호출을 멈추는 조건if n == 1: return 1
함수 호출 체인함수가 다른 함수를 호출하며 이어지는 구조r100() → r10() → r1()

아래에서 하나씩 설명합니다.


재귀 함수란?

재귀 함수(Recursive Function)란 함수가 자기 자신을 다시 호출하는 함수입니다.

python
코드 하이라이팅 중…

위 코드에서 f 함수 안에서 다시 f(n - 1)을 호출합니다. 이것이 재귀입니다.

재귀 함수의 두 가지 부분

재귀 함수는 항상 다음 두 부분으로 이루어집니다.

부분설명
기저 조건 (base case)더 이상 자기 자신을 호출하지 않고 즉시 반환하는 조건
재귀 호출 (recursive case)기저 조건에 가까워지도록 변형된 입력으로 자기 자신을 다시 호출. 예를 들어 n - 1처럼 n을 1씩 줄여서 n == 1에 도달하게 합니다

기저 조건이 없으면 어떻게 될까요?

python
코드 하이라이팅 중…
기저 조건이 없으면 무한 재귀로 오류가 발생합니다
기저 조건이 없으면 함수가 끝없이 자기 자신을 호출하다가 RecursionError가 발생합니다. RecursionError는 Python이 '재귀 호출이 너무 많다'고 알려주는 오류 메시지로, 프로그램이 중단됩니다. Python은 설정값으로 재귀 호출을 1,000번까지만 허용하는데, 이 한도는 시험과 무관합니다. 시험에서는 기저 조건에 도달하는 횟수가 훨씬 적습니다.

함수 호출 체인

재귀를 이해하기 전에, 먼저 함수가 다른 함수를 호출하는 구조를 알아보겠습니다. 함수에서 배운 것처럼, 함수는 다른 함수를 호출할 수 있습니다. 이렇게 함수들이 사슬처럼 이어지는 것을 호출 체인(chain)1이라고 합니다.

python
코드 하이라이팅 중…
출력
코드 하이라이팅 중…

이 코드는 재귀는 아니지만, 함수가 함수를 호출하는 체인 구조입니다. 만약 r100, r10, r1이 전부 같은 함수라면 어떨까요? 자기 자신을 계속 호출하는 재귀 함수가 됩니다.

호출 순서 추적하기

함수 호출 체인은 안쪽 함수부터 계산해야 합니다. 바깥 함수는 안쪽 함수의 반환값을 기다리기 때문입니다.

함수 호출 체인
r100()이 r10()을 호출하고, r10()이 r1()을 호출합니다. 반환은 안쪽 함수부터 바깥쪽으로 돌아옵니다.
단계함수계산반환값
1r1()44
2r10()30 + r1() = 30 + 434
3r100()200 + r10() = 200 + 34234
함수 호출 체인 풀이 팁
가장 안쪽(마지막으로 호출되는) 함수부터 반환값을 계산하세요. 바깥 함수로 돌아오며 하나씩 값을 채워 넣으면 됩니다.

재귀 함수의 동작 원리

함수 호출 체인에서 호출하는 함수가 자기 자신이면 재귀 함수입니다.

1부터 n까지의 합

def는 함수를 만드는 키워드, return은 결과값을 돌려주는 키워드입니다. 자세한 내용은 함수 페이지를 참고하세요.

python
코드 하이라이팅 중…
출력
코드 하이라이팅 중…

재귀 호출 추적하기

total(5)를 호출하면 다음과 같이 동작합니다.

total(5) 재귀 호출 추적
왼쪽: total(5)에서 total(1)까지 호출이 쌓이는 과정. 오른쪽: 기저 조건에서부터 반환값이 돌아오는 과정.
호출계산반환값
total(1)기저 조건 (n == 1)21
total(2)2 + total(1) = 2 + 13
total(3)3 + total(2) = 3 + 36
total(4)4 + total(3) = 4 + 610
total(5)5 + total(4) = 5 + 1015

팩토리얼 예제

팩토리얼(Factorial)은 1부터 n까지의 모든 수를 곱한 값입니다. 5!(5 팩토리얼)은 수학에서 5부터 1까지 차례로 곱하라는 뜻으로, 느낌표(!)는 팩토리얼을 나타내는 수학 기호입니다. 5! = 5 x 4 x 3 x 2 x 1 = 120

"재귀 함수란?" 섹션의 첫 예제도 이 팩토리얼 함수입니다.

python
코드 하이라이팅 중…
출력
코드 하이라이팅 중…

total(5)를 추적했던 것과 같은 방식으로 따라가 봅시다. 다른 점은 +가 *로 바뀐 것뿐입니다.

f(5)가 f(1)까지 호출을 쌓은 뒤 1, 2, 6, 24, 120을 차례로 곱해 반환하는 재귀 호출 추적 그림
왼쪽: f(5)에서 f(1)까지 호출이 쌓이는 과정. 오른쪽: 기저 조건에서부터 곱한 값이 돌아오는 과정.
호출계산반환값
f(1)기저 조건 (n == 1)1
f(2)2 * f(1) = 2 * 12
f(3)3 * f(2) = 3 * 26
f(4)4 * f(3) = 4 * 624
f(5)5 * f(4) = 5 * 24120

피보나치 예제

피보나치 수열은 앞의 두 수를 더해 다음 수를 만드는 수열입니다. 0, 1, 1, 2, 3, 5, 8, 13, ... 형태로, 두 번 자기 자신을 호출하는 다중 재귀의 대표 예제입니다.

python
코드 하이라이팅 중…
fib(3)이 fib(2)와 fib(1)로, fib(2)가 fib(1)과 fib(0)으로 갈라지는 호출 트리. 기저 조건 노드는 주황이고 반환값 1, 0, 1, 1이 초록 화살표로 올라가 fib(3) = 2가 된다
fib(3) 한 번에 함수가 5번 호출되고, fib(1)은 두 번 호출됩니다. 반환값은 아래에서 위로 더해져 2가 됩니다
출력
코드 하이라이팅 중…

fib(3)을 계산하려면 fib(2)와 fib(1)을 알아야 하고, fib(2)는 다시 fib(1)과 fib(0)을 호출합니다. 기저 조건(n <= 1)에 도달하면 멈춥니다. 그래서 fib(3) 한 번에 함수가 모두 5번 호출되고, fib(1)은 두 번 호출됩니다.

호출계산반환값
fib(0)기저 조건0
fib(1)기저 조건1
fib(2)fib(1) + fib(0) = 1 + 01
fib(3)fib(2) + fib(1) = 1 + 12

팩토리얼이 n * f(n-1)로 한 번 자기 자신을 호출한다면, 피보나치는 f(n-1) + f(n-2)로 두 번 호출한다는 점이 차이입니다. 다중 재귀 추적 방법은 아래 "실기 문제 풀이 전략"의 gamja 예제와 같습니다.

중첩 리스트 평탄화 예제

평탄화(flatten) 는 중첩된 구조를 한 겹으로 풀어 펴는 동작입니다. [1, [2, [3, 4]], 5]처럼 리스트 안에 리스트가 들어 있을 때, 재귀로 한 번씩 벗겨 내면 [1, 2, 3, 4, 5]로 만들 수 있습니다.

python
코드 하이라이팅 중…
flatten([1, [2, [3, 4]], 5]) 재귀 호출 트리. 리스트가 아닌 1, 2, 3, 4, 5는 [x]로 감싸 반환하고, 리스트 호출은 반환된 리스트를 이어 붙여 최종 결과 [1, 2, 3, 4, 5]를 만든다
호출은 위에서 아래로 내려가고, 초록 칸의 반환값은 아래에서 위로 이어 붙어 [1, 2, 3, 4, 5]가 됩니다
출력
코드 하이라이팅 중…
  • isinstance(x, list)는 x가 리스트인지 확인하는 내장 함수입니다. 리스트가 아니면(숫자·문자열 등) 더 펼칠 것이 없으므로 [x]로 감싸 돌려줍니다.
  • for item in x: result += flatten(item)은 각 요소를 다시 flatten에 넣어 얻은 리스트를 이어 붙여 하나로 모읍니다.

평탄화 + 합계를 한 번에 구하고 싶다면 sum(flatten(x)) 한 줄로 가능합니다.

python
코드 하이라이팅 중…
출력
코드 하이라이팅 중…
리스트 평탄화는 재귀가 자연스럽습니다
중첩 깊이가 정해지지 않은 리스트는 반복문만으로는 풀기 어렵습니다. 요소가 리스트인지 아닌지에 따라 자기 자신을 다시 부르는 재귀 구조가 자연스럽게 맞습니다. 평탄화 문제를 만나면 '기저 조건: 리스트 아님', '재귀 호출: 각 요소를 flatten'이라는 두 줄 패턴을 떠올리세요.

실기 문제 풀이 전략

재귀 함수 문제 풀이 순서

  1. 기저 조건 확인: if문에서 어떤 값을 반환하는지 확인
  2. 재귀 호출 파악: return문에서 자기 자신을 어떻게 호출하는지 확인
  3. 호출 추적(호출 트리) 작성3: 기저 조건에 도달할 때까지 호출을 펼치기
  4. 역순 계산: 기저 조건의 반환값부터 시작하여 위로 계산

복잡한 재귀: 두 번 이상 자기 자신을 호출하는 경우

재귀 호출이 두 번 이상 있는 경우, 각 호출의 반환값을 모두 계산해야 합니다.

python
코드 하이라이팅 중…
출력
코드 하이라이팅 중…

이 함수는 gamja(n - 1)과 gamja(n - 3) 두 개의 재귀 호출을 합니다.

다중 재귀 호출 트리
gamja(7)에서 시작하여 gamja(n-1)과 gamja(n-3) 두 갈래로 분기되는 트리 구조. 주황색 노드가 기저 조건(n<=1)입니다.
n <= 1이면 n을 반환합니다
기저 조건에서 1이 아니라 n을 반환합니다. n이 0이면 0, n이 1이면 1, n이 -1이면 -1을 반환합니다. 기저 조건의 반환값을 꼼꼼히 확인하세요.

gamja(7) 호출 추적

기저 조건에 닿을 때까지 각 호출을 분해합니다. gamja(7)부터 시작하여 gamja(n - 1) + gamja(n - 3) 형태로 한 줄씩 펼쳐 내려가고, n <= 1인 기저 조건에 도달하면 멈춥니다. 왼쪽(n - 1)을 먼저 분해하고, 오른쪽(n - 3)은 나중에 분해합니다.

text
코드 하이라이팅 중…

시험에서 풀 때, gamja(2)를 한 번 계산해 놓으면 다시 등장할 때 같은 값을 쓰면 됩니다. (실제 프로그램은 매번 다시 계산합니다.)

거꾸로 계산

모든 호출이 기저 조건에 도달했으므로, 가장 작은 값부터 거꾸로 계산합니다.

호출계산결과
gamja(-1)기저 조건 (n <= 1)-1
gamja(0)기저 조건 (n <= 1)0
gamja(1)기저 조건 (n <= 1)1
gamja(2)gamja(1) + gamja(-1) = 1 + (-1)0
gamja(3)gamja(2) + gamja(0) = 0 + 00
gamja(4)gamja(3) + gamja(1) = 0 + 11
gamja(5)gamja(4) + gamja(2) = 1 + 01
gamja(6)gamja(5) + gamja(3) = 1 + 01
gamja(7)gamja(6) + gamja(4) = 1 + 12
복잡한 재귀 풀이 팁
재귀 호출이 두 번 이상인 문제는 호출부터 펼쳐 내려가다가 기저 조건에 도달하면 거꾸로 올라오세요. 실제 재귀의 흐름대로 따라가는 것이 실수를 줄이는 방법입니다.
재귀와 반복문은 서로 바꿀 수 있습니다
재귀로 풀 수 있는 문제는 반복문으로도 풀 수 있고, 그 반대도 마찬가지입니다. 시험에서 재귀 코드가 나오면 반복문으로 바꿔 생각해 보는 것도 좋은 풀이 전략입니다. 반복문이 익숙하지 않다면 반복문 페이지를 먼저 읽어보세요.

예를 들어 total(5) 재귀 함수는 다음 반복문과 같은 결과를 냅니다.

python
코드 하이라이팅 중…
출력
코드 하이라이팅 중…

정보처리기사 실기 기출 문제

문제를 불러오는 중이에요.
문제를 불러오는 중이에요.

Footnotes

  1. chain은 "사슬"이라는 뜻입니다. 함수 A가 B를 부르고, B가 C를 부르는 것처럼 이어지는 모양을 가리킵니다. ↩

  2. ==는 두 값이 같은지 비교하는 연산자입니다. 값을 넣는 =(대입)과 다릅니다. ↩

  3. "호출 트리"는 함수가 호출되는 과정을 나무 가지처럼 그린 그림을 가리키고, "호출 추적"은 그 과정을 글로 따라가는 행위를 가리킵니다. 이 페이지에서는 같은 의미로 사용합니다. ↩


메가커피와 함께, 홈페이지 개선에 참여하세요! ☕
혹시 이용에 불편한 점이나 개선이 필요한 부분을 발견하셨나요? 댓글로 알려주시면 더 나은 감자가 될 수 있어요! 🥔 제보해주신 모든 분께 메가커피 기프티콘을 드립니다! (본인 이메일로 댓글 달아주셔야해요~)
후수학습(2개)
  • Python 클래스와 __init__
  • Python 제너레이터 표현식
정처기 감자정처기 감자

정보처리기사 합격
도와줄라고 하는 감자

실기 이론

  • 이론 공부법
  • DB
  • 네트워크/OS
  • SW 설계
  • SW 개발
  • 보안/신기술

시험 응시

  • 시험장 찾기
  • 원서 접수
  • 응시자격 서류

요약 PDF

  • 26년 3회 이론 압축
  • 26년 3회 코딩 압축
  • 초압축 25년 3회
  • 압축 25년 3회

기출문제

  • 전체 기출문제
  • 25년 3회
  • 25년 2회
  • 문제 포럼

감자 이용권

  • 이용권 구매

실기 이론

  • 이론 공부법
  • DB
  • 네트워크/OS
  • SW 설계
  • SW 개발
  • 보안/신기술

시험 응시

  • 시험장 찾기
  • 원서 접수
  • 응시자격 서류

요약 PDF

  • 26년 3회 이론 압축
  • 26년 3회 코딩 압축
  • 초압축 25년 3회
  • 압축 25년 3회

기출문제

  • 전체 기출문제
  • 25년 3회
  • 25년 2회
  • 문제 포럼

감자 이용권

  • 이용권 구매
© 2025 재현기획개발. All rights reserved.
  • 정처기 감자의 시작
  • 업데이트 로그
  • 개인정보 처리방침
  • 이용약관
상호명 : 재현기획개발 / 주소: 서울특별시 영등포구 영등포로 150, 지하1층 108호 L145 가라지(당산동1가, 생각공장 당산) / 대표: 김재현 / 전화: 010-8158-7127 / 통신판매업신고: 제2025-서울영등포-1569호 / 이메일: contact@edugamja.com / 사업자등록번호: 573-51-00999