ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] 함수의 활용
    NAN/Python 2021. 6. 20. 20:25
    728x90

     

    프로그래밍 언어를 접하면 필수적으로 배우게 되는 for, while 반복문이 있는데,

     

    이와 같은 반복문을 사용하지 않고 같은 구문을 반복하는 함수를 '재귀 함수'라고 부른다.

     

    재귀 정의

     


     

    재귀 함수

     

    def count_up(n):
      
      if n == 10:
        print('10을 달성했습니다.!')
      else:
        print(n) 
        count_up(n+1)  
    
    count_up(1)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10을 달성했습니다.!

     

    간단한 예로 카운트를 세고 목표 카운트에 도달하면 종료되는 함수를 작성하였는데,

     

    if 조건을 만족하지않는동안 계속해서 작동되는 것을 확인할 수 있었다.

     

    물론 for문을 사용하여 함수를 구성 할 수 있지만 프로그래밍을 하다 보면 이래저래 필요한 경우가 많다고 하니 

     

    지금은 이런게 있구나 하고 짚고 넘어가도록 하자

     

     


    메모화

     

     

    재귀 함수로 피보나치수열과 같은 수학 공식을 실행하게 된다면 그 수가 커지면 커질수록 상당 시간이 소요된다.

     

    간단하게 설명하자면 1부터 n번까지의 수열의 곱이 피보나치수열의 정의인데,

     

    재귀 함수로 이를 실행하게 되면 1~n까지 계산되는 동안 같은 것을 여러 번 연산하기 때문에

     

    컴퓨터의 부하, 프로그램 오류 등의 문제를 불러일으킬 수 있어 '메모화' 작업을 통해 이를 보완해주어야 한다.

     

    count = 0
    
    def fibonacci(n):
      
      print('fibonacci({})를 구합니다.'.format(n))
      global count
      count += 1
    
      if n == 1:
        return 1
      if n == 2:
        return 1
      else:
        return fibonacci(n - 1) + fibonacci(n - 2)
    fibonacci(10)
    print('-----')
    print('fibonacci(10) 계산에 활용돠니 덧셈 횟수는 {}번입니다.'.format(count))    
    
    fibonacci(10)를 구합니다.
    fibonacci(9)를 구합니다.
    fibonacci(8)를 구합니다.
    fibonacci(7)를 구합니다.
    =========생략===========
    fibonacci(3)를 구합니다.
    fibonacci(2)를 구합니다.
    fibonacci(1)를 구합니다.
    fibonacci(4)를 구합니다.
    =========생략===========
    fibonacci(1)를 구합니다.
    fibonacci(2)를 구합니다.
    fibonacci(3)를 구합니다.
    fibonacci(2)를 구합니다.
    fibonacci(1)를 구합니다.
    fibonacci(6)를 구합니다.
    fibonacci(5)를 구합니다.
    =========생략===========
    fibonacci(3)를 구합니다.
    fibonacci(2)를 구합니다.
    fibonacci(1)를 구합니다.
    fibonacci(2)를 구합니다.
    fibonacci(3)를 구합니다.
    =========생략===========
    fibonacci(3)를 구합니다.
    fibonacci(2)를 구합니다.
    fibonacci(1)를 구합니다.
    fibonacci(2)를 구합니다.
    fibonacci(3)를 구합니다.
    =========생략===========
    fibonacci(2)를 구합니다.
    fibonacci(5)를 구합니다.
    fibonacci(4)를 구합니다.
    fibonacci(3)를 구합니다.
    fibonacci(2)를 구합니다.
    fibonacci(1)를 구합니다.
    fibonacci(2)를 구합니다.
    =========생략===========
    fibonacci(3)를 구합니다.
    fibonacci(2)를 구합니다.
    fibonacci(1)를 구합니다.
    fibonacci(2)를 구합니다.
    fibonacci(3)를 구합니다.
    =========생략===========
    fibonacci(5)를 구합니다.
    fibonacci(4)를 구합니다.
    fibonacci(3)를 구합니다.
    =========생략===========
    fibonacci(4)를 구합니다.
    fibonacci(3)를 구합니다.
    fibonacci(2)를 구합니다.
    fibonacci(1)를 구합니다.
    fibonacci(2)를 구합니다.
    fibonacci(3)를 구합니다.
    fibonacci(2)를 구합니다.
    =========생략===========
    fibonacci(1)를 구합니다.
    fibonacci(2)를 구합니다.
    -----
    fibonacci(10) 계산에 활용돠니 덧셈 횟수는 109번입니다.
    
    #혼자공부하는파이썬 예시 발췌

     

    이처럼 반복되는 연산이 많기 때문에 재귀 함수를 사용할 때는 메모화 작업을 함께 해주는 것이 바람직하다.

     

     

    dic = {
        1:1,2:1
      }
    
    def fibonacci(n):
      if n in dic:
        return dic[n]
      else:
        output = fibonacci(n - 1) + fibonacci(n - 2)
        dic[n] = output
        return output    
    
    print('fibonacci(10):', fibonacci(10))    
    
    
    fibonacci(10): 55

     

     

    이처럼 같은 역할을 하는 재귀 함수라도 '메모화'를 통해 작업하면 좀 더 안정적이고 빠른 시간 안에 결과를 받을 수 있다.

     


    global 

     

    위의 예시에서 함수 밖에 있는 count를 가져와 사용하였는데 이는 global 키워드를 사용하였기 때문에 가능했다.

     

    이와 같은 방식으로 변수에 접근하는 것을 '참조'라고 한다.

     

    count = 0
    
    def fibonacci(n):
      
      print('fibonacci({})를 구합니다.'.format(n))
      global count
      count += 1

     

     

     

    만약 함수 내부에서 외부에 있는 변수를 활용하고자 한다면 이처럼 global '변수'를 반드시 표기하자

     

    만약 기재하지 않을 경우

     

    UnboundLocalError : local variable '변수' referenced before assignment라는 에러 코드가 뜬다.

     

     


     

    조기 리턴

     

    우리는 함수를 배우면서 print( ) 대신 return 키워드를 사용하기 시작했는데,

     

    관례처럼 if와 else를 작성한 후 각각 문단의 마지막에 return 키워드로 값을 반환하였다.

     

    하지만 굳이 else를 작성하지 않고 if의 조건에 충족할 경우 return으로 값을 반환한다고 표기하게 되면 어떨까?

     

    또 else를 적지 않았음에도 코드가 실행되는 데에는 아무 문제가 없다면 들여 쓰기 단계가 줄기 때문에

     

    코드를 조금 더 쉽게 읽을 수 있게 될 것이다. 이렇듯 중간에 return 키워드를 사용하는 것을 조기 리턴이라고 부른다.

     

    def fibonacci(n):
      if n in dic:
        return dic[n]
      else:
        output = fibonacci(n - 1) + fibonacci(n - 2)
        dic[n] = output
        return output  
        
        
    def fibonacci(n):
      if n in dic:
        return dic[n]
      
      output = fibonacci(n - 1) + fibonacci(n - 2)
      dic[n] = output
      return output   

     

     

    이런 사소하게 느껴지는 부분이 프로그래머 개인의 테크닉이라고 하니 알아도록하자.

     


    'NAN > Python' 카테고리의 다른 글

    [Python] 예외 처리 try, except, finally  (0) 2021.06.20
    [Python] 함수 고급 (튜플,map,filter,lambda)  (0) 2021.06.20
    [Python] 반복문 while, for  (0) 2021.06.06
    [Python] bool 연산자와 조건문  (0) 2021.06.06
    [Python] 자료형 - set  (0) 2021.06.04
Designed by Tistory.