미소를뿌리는감자의 코딩
map, lambda와 enumerate - python 본문
오늘 코딩 문제들을 풀어보면서, 다른 팀원분들의 코드에서 lambda와 enumerate를 보게 되었다.
아마,,, 3년 전엔 기억했던 것 같은데, 너무 가물가물치 해져서 다시 알아보아야 할 것 같다.
1. map
list와 같은 변수에서 하나씩 꺼내서 함수에 적용 후 결과를 map 객체로 반환하는...
map(function, iterable, ...)
map() 함수는 입력으로 받은 iterable(s)의 각 요소에 함수를 적용한 결과를 포함하는 map 객체를 반환한다.
이를 다른 data type으로 변환하기 위해서는 list(), set() 등의 생성자를 사용할 수 있다.
즉, map 함수 이용 -> map 객체 반환 -> list 또는 set으로 변환
예제 1: 각 요소의 제곱 계산하기
def square(number):
return number ** 2
numbers = [1, 2, 3, 4, 5]
squared = map(square, numbers)
print(list(squared))
map (함수, 변수들 like list...)
square 함수에 numbers라는 변수가 들어가서 나오는 것이므로, map에는 1, 4, 9, 16, 25 가 저장되게 된다. -> map 객체 반환
이를 list(squared) 를 통해서 -> list 또는 set으로 변환
출력해주었다.
예제 2: 여러 리스트 처리하기
def add(x, y):
return x + y
list1 = [1, 2, 3]
list2 = [4, 5, 6]
result = map(add, list1, list2)
print(list(result)) # 결과 [5,7,9]
이런식으로도 map 함수를 이용할 수 있다. add(list1, list2) 와 같이 생각되는 것은 실제로 적용을 하지 못한다.
왜냐?! add함수가 단일 숫자를 인자로 받도록 정의되어 있기 때문이다.
따라서 이를 그리고자 할 때는 하나하나씩 인자를 꺼내올 수 있는 map을 이용할 수 있다. -> add(list1[i], list2[i]) 가 적용된다.
2. lambda
우리의 친구 ChatGPT에게 lambda에 대해서 설명해달라고 하였다.
lambda 함수는 작은 익명 함수를 정의하는 데 사용된다. "익명" -> 함수들에게 고유한 식별자가 없다 라는 것을 의미한다.
즉, 간단한 함수를 한 줄의 코드로 표현할 때 유용하다.
lambda 변수들 : 함수
lambda arguments: expression
기본적인 골격은 위와 같다.
arguments -> 함수로 전달할 인수
expression -> 함수 반환 값을 계산하는 식
따라서 return 문을 사용하지 않아도 된다.
예제 1: 단순한 덧셈
add = lambda x, y: x + y
print(add(5, 3))
변수 x, y에 대해서 x+y를 한 후 return 하는 것을 볼 수 있다.
예제2: 조건부 표현식
max_value = lambda x, y: x if x > y else y
print(max_value(8, 5))
반환 값들이 앞뒤로 있다는 점이 신기한 것 같다.
예제3: 리스트 정렬
items = [('apple', 2), ('banana', 4), ('cherry', 1)]
items.sort(key=lambda x: x[1])
print(items)
key = lambda x : x[1] 에서, x로 items[i]가 들어오게 된다.
즉, ('apple', 2) 가 들어오게 되고, x[1]인 2를 기준으로 정렬하게 된다.
1&2. lambda, map
lambda vs map
- lambda 변수들 : 함수
- map (함수, 변수들 like list...)
변수와 함수의 위치가 바뀐 것을 알 수 있다. 물론 같은 함수는 아니지만, 비교해보면 좋을 것 같다.
예제 1: 리스트의 각 요소에 대해 제곱 값을 계산하는 예:
numbers = [1, 2, 3, 4]
squared = list(map(lambda x: x**2, numbers))
map과 lambda에 대해서 배오고 오니 위 코드가 이해가 되기 시작했다.
우선 lambda x: x**2 는 x가 변수 x**2 가 함수이다.제곱을 반환하는 함수임을 알 수 있다.
다르게 적어보면, list(map(제곱 함수, numbers)) 이다.
이제 map에 대해서 이해해보면, numbers에서 각각의 index value들을 제곱 함수에 전해주게 된다.
list(1, 4, 9, 16) 임을 알 수 있다. list 괄호 안에 있는 것은, map 객체 임을 알 수 있으며, 이를 list 로 변환하여,
squared = [1, 4, 9, 16] 임을 알 수 있다.
순서를 좀 정리해보면, number에서 index 요소들을 하나씩 전달, lambda에서 x로 받고, x**2 함수 적용 후 반환
즉, numbers -> x -> x**2 이다.
하나 더 알아보자.
예제 2: 여러 시퀸스 처리하기
numbers1 = [1, 2, 3]
numbers2 = [4, 5, 6]
result = map(lambda x, y: x + y, numbers1, numbers2)
print(list(result))
numbers 1, numbers2 의 값 각각을 x, y에 전달 x+y 실행 후 반환.
1, 4 -> x, y -> x+y 반환 (5)
2, 5 -> x, y -> x+y 반환 (7)
3, 6 -> x, y -> x+ y 반환 (9)
lambda 함수의 장단점
장점
- 간결성: 익명 함수를 한 줄의 코드로 정의할 수 있음.
- 익명성: 이름을 정의할 필요 없음.
단점
- 제한된 표현력: 복잡한 로직이나 여려 행의 코드를 포함할 수 없음
- 가독성 문제: lambda 함수는 읽기 어려울 수 있음
map 함수의 장단점
장점
- 코드 간결성: 컬렉션의 모든 요소에 함수를 적용하여 새로운 컬렉션을 생성하는 간단한 방법
선은: 일반적인 반복문보다 효율적일 수 있음 -> python 내장 함수는 종종 최적화 되어있기 때문
단점
- 한정된 사용: 모든 요소에 동일한 함수를 적용하는 상황ㅇ에만 가능
- 지연 실행: map() 은 즉시 실행되지 않고, 반복 가능한 객체를 반환 -> 따라서 결과를 확인하기 위해 list나 set으로 변환해야 함.
3. enumerate
for 인덱스, 값 in enumerate (순회 가능 컬렉션):
print(인덱스, 값)
iterable (순회 가능) 한 컬렉션
컬렉션의 각 요소를 인덱스와 요소의 쌍으로 구성을 반환 (tuple 형태로)
enumerate(iterable, start = 0)
순회를 시작하는 부분은 default로 0부터 시작한다.
예제 1: 리스트 순회하기
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits):
print(index, fruit)
for 인덱스, 값 in enumerate (순회 가능 컬렉션):
print(인덱스, 값)
을 할 수 있다.
예제 2: 시작 인덱스 변경하기
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits, start=1):
print(index, fruit)
장점:
- 가독성 향상: 코드의 의도를 더 명확하게 표현 가능. 인덱스와 요소를 동시에 처리 가능
- 유연성: 시작 인덱스를 설정 가능.
- 효율성: 별도의 카운터 변수를 관리할 필요가 없다.
'코딩 이야기' 카테고리의 다른 글
[Intellij] How to change project name (0) | 2024.03.02 |
---|---|
[github] private repository에 project 올리기 (0) | 2024.03.02 |
python의 sort()의 시간 복잡도 (0) | 2024.02.21 |
ORM과 Spring 탄생 배경 (0) | 2024.02.21 |
Counter, hash table, 그리고 python에서는 조금 다른 시간 복잡도 (1) | 2024.02.07 |