Python에서의 재귀
프로그래밍에는 재귀라는 개념이 있습니다 - 함수가 자기 자신을 호출하는 경우입니다.
예시 . 카운터를 사용한 간단한 재귀
재귀를 사용하여
1부터 10까지의 숫자를
출력해 봅시다:
i = 1
def func():
global i
print(i)
i += 1
if i <= 10:
func() # 여기서 함수가 자기 자신을 호출합니다
func()
이 코드가 어떻게 동작하는지 논의해 봅시다.
전역 변수 i와
함수 func가 있습니다. 함수 내부에서는
변수 i의 내용이 콘솔에 출력된 후
그 값에 1이 더해집니다.
변수 i가 10보다 작거나
같으면 함수가 다시 호출됩니다. 변수 i가
전역 변수이기 때문에 함수가 새로 호출될 때마다
이전 호출에서 설정된 변수 i의 값을
가지게 됩니다.
그 결과, i가 10보다 커질 때까지
함수가 자기 자신을 계속 호출하게 됩니다.
기억하세요, 우리의 경우에서는 if 없이는
함수를 실행할 수 없습니다 - 만약 그렇게 하면
함수의 무한 호출이 발생합니다.
예시 . 중첩된 리스트의 요소 출력을 위한 재귀
재귀는 가장 흔히 다양한 중첩 수준의 리스트를 순회하는 데 사용됩니다. 다음과 같은 리스트가 있다고 가정해 봅시다:
lst = [1, [2, 3], [[4, 5], [6, 7, 8, [9]]]]
이 리스트를 순회하는 함수를 만들어 봅시다.
먼저, 단순한 원시 값, 즉 리스트에서 추출된
숫자만 콘솔에 출력되도록 조건을 설정해야 합니다.
요소가 객체, 예를 들어 중첩된 리스트인 경우에는
함수가 자기 자신을 호출하도록 해야 합니다,
즉 재귀가 발생합니다. 요소의 타입을 확인하기 위해
함수 isinstance를 사용하겠습니다.
우리의 예시에서는 isinstance의 첫 번째 매개변수에
el를, 두 번째에는 타입 list를
작성합니다:
def func(lst):
for el in lst:
if isinstance(el, list):
func(el)
else:
print(el)
함수를 호출하면 중첩된 리스트의 모든 숫자가 한 줄로 출력됩니다:
func(lst) # 1, 2, ... 8, 9를 출력합니다
예시 . 중첩된 리스트 요소에 대한 연산을 위한 재귀
재귀는 중첩된 리스트의 요소에 대한 다양한 연산에도 적용할 수 있습니다. 다음과 같은 리스트가 있다고 가정해 봅시다:
lst = [1, [2, 3], [[4, 5], [6, 7, 8, [9]]]]
모든 요소의 합을 구해 봅시다.
함수 내에서 숫자의 합이 누적될 변수 res를
선언합니다.
조건문에서는 요소가 복잡한 객체인 경우
함수 func의 매개변수로 들어가 합에
더해지도록 작성합니다. 이는 요소가
원시 값이 될 때까지 재귀에 들어간다는 것을
의미합니다. 이 경우 요소는 단순히
res에 기록된 합에 더해집니다:
def func(lst):
res = 0
for el in lst:
if isinstance(el, list):
res += func(el)
else:
res += el
return res
함수를 호출하고 그 결과를 콘솔에 출력해 봅시다:
print(func(lst)) # 45를 출력합니다
예시 . 리스트에 누적하기 위한 재귀
재귀를 사용하여 중첩된 리스트를 하나의 1차원 리스트로 펼칠 수 있습니다. 다음과 같은 리스트가 있다고 가정해 봅시다:
lst = [1, [2, 3], [[4, 5], [6, 7, 8, [9]]]]
함수에 원본 리스트의 요소가 누적될 빈 리스트
res를 작성해 봅시다. 그런 다음 루프를
실행하고 조건을 설정합니다 - 요소가 리스트인 경우
메서드 extend에 들어갑니다. 이 메서드는
한 리스트의 요소를 두 번째 리스트의 끝에
연결합니다, 즉 중첩된 리스트의 요소가
리스트 res의 끝에 들어갑니다:
def func(lst):
res = []
for el in lst:
if isinstance(el, list):
res.extend(func(el))
else:
res.append(el)
return res
print(func(lst))
수행된 코드의 결과:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
실습 문제
임의의 중첩 수준을 가진 딕셔너리의 모든 숫자 요소를 출력하세요:
{
'a': {
'b': 1,
'c': 2,
'd': {
'e': 3,
'f': 4
}
},
'j': {
'h': 5,
'k': 6,
},
'l': 7
}
이전 문제의 딕셔너리 요소들의 합을 구하세요.
이전 문제의 딕셔너리에서 원시 요소들의 리스트를 얻으세요.