티스토리 뷰

오늘 다룰 아이들은 작은 친구들이다. 큰 함수 단원에 속한 아이들이며 반드시 알아야 할 함수이니 천천히 배워보

  1. 재귀함수
  2. 유용한 내장 함수

어렸을때부터 재귀는 무서워했던 단어였다. 수학에서도 점화식 풀면서 싫어했고, 영어에서도 재귀대명사가 있을 정도니.. (영어는 정말 못한다) 원래 자리로 돌아온다라는 사전적의미를 갖고있지만 돌아가는건 항상 내 머리였다. 수학을 끝내서 더이상은 안볼줄 알았던 단어가 돌아오고 말았다. 아니 '재귀'라는 단어 자체도 너무 못생긴거아닌가..? 어떻게 이렇게 정이 안가는지 모르겠다.

또, 알고리즘 풀 때와 특정 함수를 정의할 때 반드시 필요하기 때문에 잘 알아야한다. 나중엔 stack 파트에서 재귀 호출도 나온다..


재귀함수

: 함수 내부에서 자기 자신을 호출하는 함수

  • 특정 알고리즘(점화식 등)을 표현할 때 변수의 사용이 줄어 코드의 가독성이 좋아진다
  • 특이사항 : 1개 이상의 base case(종료 조건)이 존재하며, 수렴하도록 함수를 작성한다
  • 큰 단위에서 작은 단위로 줄여 나갈 때 주로 사용한다 

예시 : Factorial (=!, 팩토리얼)

 

  • factorial 함수는 자신을 재귀적으로 호출하여 입력된 숫자(input) 값의 팩토리얼을 계산한다
  • 재귀 호출은 n이 0이 될 때까지 반복하는 호출이며, 종료 조건을 통해 멈추게 할 수 있다
  • 큰 문제를 작은 단위의 문제로 분할하고, 재귀 호출 결과들을 조합하여 최종 결과를 도출한다 

 

Factorial
base case = 종료조건 = 기저조건

 

코드로 나타내면 아래와같다. 


def factorial(n):
    # 종료 조건(=기저 조건) : n = 0이면 1을 반환한다
    if n == 0:
        return 1
    # 재귀 호출 : n과 n-1의 팩토리얼을 곱한 결과를 반환한다
    return n * factorial(n - 1)     # return에 자기 함수를 다시 넣음으로써 재귀 함수를 호출

# 함수 계산 예시
print(factorial(5)) # 120
 

 

무시무시한 재귀라는 단어에 비하면 코드는 굉장히 간단한데, 이것이 재귀 함수 호출의 장점이다. 여러번 반복할 것을 알아서 스스로 반복하기 때문에 코드만 잘 사용한다면 가독성은 굉장히 좋다고 볼 수 있다. 물론 나중에 재귀 함수의 반복 호출중 데이터가 중복되는 것이 많아 같은 데이터를 여러번 호출하지 않고 저장해뒀다가 사용하는 방식도 나오면서 복잡해질 예정이다..ㅠ       


유용한 함수 (map, zip)

map(function, iterable)

: 순회 가능한 데이터구조의 모든 요소에 함수를 적용하고 적용한 데이터들을 map object로 반환한다. 처음에 알고리즘을 무작정 풀면서 공백이 포함된 데이터들을 input으로 array 받아올 때 map을 몰라서 항상 코드가 길어졌는데, map함수를 배우고나서는 너무편해졌다.  

예를들어서


# map(function, iterable) = map(함수, 시퀸스)
# input data : 1 2 3 4 5 를 정수로 넣으려면
arr = input().split()
arr_1 = int(arr[0])
arr_2 = int(arr[1])
arr_3 = int(arr[2])
arr_4 = int(arr[3])
arr_5 = int(arr[4])
print(arr)          # ['1', '2', '3', '4', '5'] 데이터는 문자열 타입으로 들어 왔고, list로 넣을면 메서드를 사용해야한다. 
print(type(arr))    # <class 'list'>

arr = map(int, input().split())
print(type(arr))    # <class 'map'>
print(arr)          # <map object at 0x0000020D548D1FA0>

arr = list(arr)     # list로 변환
print(type(arr))    # <class 'list'>
print(arr)          # [1, 2, 3, 4, 5]
print(type(arr[0])) # <class 'int'>
 
# 주로 쓰는 input 형식 공백으로 나누어진 데이터를 map 함수를 통해 int로 모두 형변환한 map 데이터를 list로 만든다.
arr = list(map(int, input().split()))
 

 

위의 arr은 자동으로 리스트 데이터로 받았고, 데이터를 사용하려면 array의 index를 받으면서 정수 변환인 int()함수를 각각사용해줘야 한다. 하지만 map 함수를 통해 반복이 필요 없이 한번에 형변환 할 수 있는 것이다. 알고리즘을 풀다보면 적절한 상황에 따라 사용하는 방법을 터득할 수 있다.


zip(*iterables)

: 임의의 반복 가능한 데이터들을 모아 튜플로 원소로 하는 zip object를 반환한다. 사실 초반에는 정말 쓴적 없는데, 일부 데이터를 가공할 때 굉장한 능력을 발휘한다. 아직 여기까지의 진도로는 배우진 않지만, 나중에 2차원 배열 데이터를 진행하면서 전치를 할 때, 반복문 2개를 사용하며 좌표를 바꿔줘야하는 과정 대신, zip 함수를 통해 단 한줄로 바꿔줄 수 있다. 여기서는 간단하게만 다루려고 한다.


# zip(*iterables) = zip(가변인자 시퀸스)
boys = ['hyeon', 'yeop']
girls = ['yeon', 'ria']
pair = zip(boys, girls)

print(pair)             # <zip object at 0x0000022E4A2C4680> 예상했겠지만 변환이 한번 더 필요하다
pair = list(pair)       # 리스트 형변환
print(pair)             # [('hyeon', 'yeon'), ('yeop', 'ria')]
print(type(pair[0]))    # <class 'tuple'> 튜플로 묶여있는 모습
 

 


 

필수로 알아야할 함수와 알면 굉장히 편리한 내장함수들을 살펴봤는데, 지금은 머릿속에 잘 들어오지 않아도 나중에 살기위해서, 시간초과를 없애기 위해서 반드시 써야할 방법들이다. 다음시간에는 lambda 함수와  packing&unpacking에 대해 간단하게 알아볼 것이다.

728x90
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함