TIL(24.12.21)

채채·2024년 12월 21일

Today I Learned

목록 보기
39/75

베이직반 수업 빠져서 keyword만 친구한테 얻어와서 직접 자료 찾아보며 공부한 내용으로 작성,,,

12/20(금) 베이직반 수업 키워드

  1. map 함수
  2. 재귀함수
  3. 무명함수(람다함수)

1. map 함수

(코딩테스트 문제 풀 때 많이 나왔던 함수!
주로 map(int,input().split())으로 많이 썼었는데, 이번에 자세히 공부해봐야겠음.)

  • map() 함수는 함수와 이터러블(반복 가능한 객체)을 인자로 받아서, 함수가 이터러블의 각 요소에 적용된 결과를 반환하는 함수.
  • 즉, map()은 주어진 함수가 이터러블 객체의 모든 요소에 대해 적용되도록 도와줌.
  • 결과는 map 객체로 반환되며, 보통 list() 함수와 함께 사용하여 리스트 형태로 변환.

기본 구문

map(function, iterable)
  • iterable이란 ? 리스트, 튜플, 문자열 등 반복 가능한 객체
    (아,! function, iterable이라서 int, input()이었구나! input은 문자열로 iterable)

예시

  1. 기본 예시: 리스트의 각 요소에 함수 적용
# 두 숫자의 합을 구하는 함수
def add_two(x):
    return x + 2

# 리스트에 add_two 함수를 적용
numbers = [1, 2, 3, 4]
result = map(add_two, numbers)

# map 객체를 list로 변환하여 출력
print(list(result))  # 출력: [3, 4, 5, 6]
  1. 람다 함수와 함께 사용
    람다 함수는 간단한 함수를 한 줄로 정의할 수 있는 무명 함수. map()과 함께 사용하면 코드가 더 간결해짐.
numbers = [1, 2, 3, 4]
result = map(lambda x: x * 2, numbers)  # 각 요소를 두 배로 만들기

print(list(result))  # 출력: [2, 4, 6, 8]
  1. 여러 이터러블을 처리
    map()은 두 개 이상의 이터러블도 처리할 수 있음.
    이 경우, 각 이터러블의 동일한 인덱스에 있는 요소들에 대해 함수를 적용.
# 두 리스트의 대응되는 요소를 더하는 함수
def add_elements(x, y):
    return x + y

list1 = [1, 2, 3]
list2 = [4, 5, 6]

result = map(add_elements, list1, list2)
print(list(result))  # 출력: [5, 7, 9]
  1. 문자열에서 각 문자 대문자로 변환
words = ["apple", "banana", "cherry"]
result = map(str.upper, words)

print(list(result))  # 출력: ['APPLE', 'BANANA', 'CHERRY']

map()의 장점

  • 효율성: map()은 한 번에 전체 이터러블을 처리하는 방식으로, 함수가 각 요소에 직접적으로 적용되므로 속도가 빠를 수 있음. 특히, 람다 함수와 함께 사용하면 코드가 간결하고 실행도 효율적임.
  • 코드 간결화: map()은 반복문을 쓰지 않고, 함수적 방식으로 문제를 해결할 수 있어 코드가 간결해짐.

주의사항

  • map() 함수는 결과를 즉시 계산하지 않고 지연 평가(lazy evaluation) 방식을 사용함. 결과를 보기 위해서는 list(), tuple(), set() 등의 함수를 사용하여 결과를 컬렉션으로 변환해야 함.
  • 여러 이터러블을 입력할 경우, 가장 짧은 이터러블의 길이에 맞춰 계산이 이루어짐.

지연평가란 ?

  • 이 객체는 값을 즉시 계산하지 않고, 실제로 값이 필요할 때 (예: list(), tuple(), set() 등으로 변환할 때) 평가됨.
  • 지연 평가는 메모리 사용을 효율적으로 만들며, 대용량 데이터를 처리할 때 유용함. 예를 들어, 모든 요소를 한 번에 메모리에 저장하지 않고, 필요할 때만 계산을 수행하므로 메모리 소비를 줄일 수 있음.

2. 재귀함수

영어 공부할때나 들어본 재귀,,, ㅠ (love yourself)

  • 재귀대명사의 재귀처럼 재귀함수도 재귀(Recursion)는 자기 자신을 호출하는 것을 의민한다고 함.

  • 즉, 어떤 과정이나 함수가 자기 자신을 반복적으로 호출하여 문제를 해결하는 방식.

  • 재귀는 문제를 더 작은 문제로 나누어서 해결할 때 유용한 방법.

  • 각 호출은 문제를 점차적으로 간소화하여 기본 조건(base case)에 도달할 때까지 자기 자신을 반복해서 호출하고, 기본 조건에 도달하면 계산을 종료하고 결과를 반환.

  • 자기 자신을 호출하는 특성 때문에, 재귀는 자기 참조(self-reference)의 개념을 갖고 있음.

  • 수학이나 컴퓨터 과학에서 재귀는 문제를 분할하고 해결하는 방법으로 자주 사용됨. 예를 들어, 팩토리얼, 피보나치 수열, 트리 탐색 등에서 재귀가 흔히 사용됨.

재귀 함수의 구조

  • 기본 사례(Base Case): 재귀 함수가 자기 자신을 호출하는 것을 멈추게 하는 조건. 이 조건이 없으면 재귀 호출이 무한히 계속되어 프로그램이 종료되지 않을 수 있음.

  • 재귀 호출(Recursive Call): 함수가 자기 자신을 호출하여 문제를 더 작은 단위로 나누고, 결국 기본 사례에 도달할 수 있게 함.


재귀 함수의 예시

  1. 팩토리얼 함수

    팩토리얼은 n!로 나타내며, n! = n (n-1) (n-2) ... 1입니다. 이를 재귀 함수로 구현할 수 있음.

def factorial(n):
    # 기본 사례: n이 0 또는 1일 때 팩토리얼은 1
    if n == 0 or n == 1:
        return 1
    # 재귀 호출: n * (n-1)!
    else:
        return n * factorial(n - 1)

# 테스트
print(factorial(5))  # 출력: 120

동작 설명:
factorial(5) 호출: 5 * factorial(4)
factorial(4) 호출: 4 * factorial(3)
factorial(3) 호출: 3 * factorial(2)
factorial(2) 호출: 2 * factorial(1)
factorial(1) 호출: 기본 사례이므로 1 반환
각 호출이 반환되면서 값을 계산하고, 최종적으로 5 * 4 * 3 * 2 * 1 = 120이 됩니다.

  1. 피보나치 수열

    피보나치 수열은 다음과 같이 정의됨.
    f(0) = 0
    f(1) = 1
    f(n) = f(n-1) + f(n-2) (n >= 2)

def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)

# 테스트
print(fibonacci(5))  # 출력: 5 (0, 1, 1, 2, 3, 5)

재귀 함수 사용 시 주의점

  • 효율성: 재귀 함수는 호출이 반복될 수 있기 때문에, 반복적인 계산이 발생할 수 있음.

  • 예를 들어, 피보나치 수열의 경우 중복된 계산이 많이 발생할 수 있습니다. 이 문제를 해결하려면 메모이제이션(Memoization) 기법을 사용할 수 있음.

  • 스택 오버플로우: 너무 깊은 재귀 호출은 호출 스택이 한계를 초과할 수 있으므로, 재귀의 깊이를 조절하거나 반복문으로 바꿀 필요가 있음.

결론

  • 재귀 함수는 자기 자신을 호출하여 문제를 해결하는 방법이며, 주로 문제를 더 작은 단위로 분할하여 해결하는 데 유용함. * 그러나 종료 조건이 정확히 설정되어야 하며, 지나치게 깊은 재귀 호출은 효율성 문제나 스택 오버플로우를 일으킬 수 있음.

3. 람다함수

24.12.19 TIL에 정리함. 링크

profile
화이팅

0개의 댓글