[파이썬] 재귀 함수, 합성 함수

재귀 함수: 자기 자신의 함수를 함수 내 연속적으로 호출하여 처리하는 함수
합성 함수: 다른 함수를 매개 변수로 받거나 반환하여 처리하는 함수
 

I. 재귀 함수

  • 재귀 함수 사용 시 별도의 순환문을 사용하지 않아도 반복 처리 효과
  • 파이썬에서는 재귀 함수를 무한정 사용할 수 없도록 제한
  • [예제] 함수 재귀 호출
import timeit

def func1(list1) :
    if len(list1) == 1 :        # 마지막 처리 로직으로 무한 수행 방지
        return list1[0]
    head, *tail = list1         # 처리값 감소 위해 첫 번째 원소는 head, 나머지 원소는 tail에 삽입
    return head + func1(tail)   # tail을 인자로 전달해서 자신을 호출

time1 = timeit.timeit('func1([1,2,3])', setup = "from __main__ import func1", number = 1000000)
print("재귀함수 처리 시간:", time1)

def func2(list2) :              # 재귀 함수 처리 시간과 비교하기 위해 순환문 사용
    result = 0
    for i in list2 :
        result += i
    return result

time2 = timeit.timeit('func2([1,2,3])', setup = "from __main__ import func2", number = 1000000)
print("순환문   처리 시간:", time2)

[결과]
귀함수 처리 시간: 0.8320854999999999
순환문   처리 시간: 0.26898349999999993
  • 재귀함수와 순환문 처리 성능 비교 시 재귀 함수 호출 시 함수를 계속적으로 생성하여 처리해야 하므로 순환문 처리 성능이 높음

 

II. 합성 함수

  • 함수도 객체이므로 다른 객체처럼 인자로 전달하여 사용 가능
  • [예제] 합성 함수 처리
import math

def add(a, b) :     # 인자로 전달할 함수 정의
    return a + b

def power(func, *args, z=None) :    # 전달받는 함수와 인자를 매개변수로 정의
    result = func(*args)            # 인자를 전달 받아 수행
    if z :
        result = math.pow(result, z)    # 키워드 인자가 들어오면 합한 값을 제곱
    return result

print(power(add, 1, 3, z = 2))

[결과]
16.0

 

III. 재귀 함수 실행 시 객체 이름공간 사용

  • 함수도 객체이므로 함수 자체 이름공간과 함수 내부 지역 이름공간이 생성
  • 함수 정의 시 생성된 이름공간은 함수 실행 시 공유하여 사용 가능
  • [예제] 순환문 없이 순환 수행
def recursion(iterable) :                       # 하나의 매개변수를 가지는 재귀 함수
    if not isinstance(iterable, list) :         # 매개변수 자료형이 리스트 클래스가 아니면 종료
        return "처리 불가"
    if not hasattr(recursion, "result") :       # 함수 객체에 속성이 없으면 빈 리스트 할당
        recursion.result = []
    if len(iterable) == 1 :                     # 반복 원소의 길이가 1이면 
        recursion.result.append(iterable.pop()) # 마지막 원소를 함수 객체의 속성에 추가 후 종료
        return None
    
    recursion.result.append(iterable.pop(0))    # 원소를 하나씩 객체 속성에 추가
    return recursion(iterable)                  # 자기 함수 호출

recursion([1,2,3])
print(recursion.result)

print(recursion("문자열 처리"))

[결과]
[1, 2, 3]
처리 불가

 

[참고]

  • 잇플, “한 권으로 개발자가 원하던 파이썬 심화 A to Z”, 2019.11

콘텐츠 사용 시 출처 표기 부탁 드리고, 궁금한 점이나 의견은 댓글 남겨주세요^^