파이썬의 `map()` 함수는 주어진 함수를 순회 가능한(iterable) 객체의 각 요소에 적용하여 새로운 값을 반환하는 내장 함수 입니다. 이 함수는 원본 데이터를 변경하지 않고 새로운 변환된 데이터를 생성하는데 사용됩니다. `map()` 함수의 기본 구문은 다음과 같습니다.
# 하나의 iterable을 사용하는 경우
map(function, iterable)
# 하나 이상의 iterable을 사용하는 경우, iterable의 개수와 함수의 인자가 같아야 합니다.
map(function, iterable1, iterable2, ...)
- `function`: 각 요소에 적용할 함수 입니다. 이 함수는 반드시 뒤에 따라올 iterable의 개수와 일치하는 인자를 받아야 합니다. `iterable`의 각 요소에 이 함수가 적용됩니다.
- `iterable`: 변환하고자 하는 데이터를 포함하는 순회 가능한(iterable) 객체입니다. 주로 리스트, 튜플, 세트 등이 사용됩니다.
예를 들어, 다음은 `map()` 함수를 사용하여 리스트의 모든 요소의 제곱하는 예제입니다.
def square(x):
return x ** 2
numbers = [1, 2, 3, 4, 5]
squared_numbers = map(square, numbers)
# map 객체를 리스트로 변환하여 결과를 얻을 수 있음
squared_numbers_list = list(squared_numbers)
위 코드에서 `map()` 함수는 `square()` 함수를 `numbers`리스트의 각 요소에 적용하고 그 결과로 새로운 `map` 객체를 반환합니다. 나중에 이 객체를 리스트로 변환하면 `[1, 4, 9, 16, 25]`와 같이 각 요소가 제곱된 값으로 구성된 리스트를 얻을 수 있습니다.
`map()` 함수는 다양한 데이터 변환 작업에서 유용하게 활용됩니다. Lambda 함수나 사용자 정의 함수를 `map()` 함수에 전달하여 원하는 작업을 수행할 수 있습니다.
다음은 위의 square 함수를 람다 함수로 전환한 예입니다.
numbers = [1, 2, 3, 4, 5]
squared_numbers = map(lambda x: x ** 2, numbers)
squared_numbers_list = list(squared_numbers)
print(squared_numbers_list) # 출력: [1, 4, 9, 16, 25]
다른 예도 봅시다.
names = ["alice", "bob", "charlie", "david"]
formatted_names = map(lambda name: name.catipalize(), names)
formatted_names_list = list(formatted_names)
print(formatted_names_list) # 출력: ['Alice', 'Bob', 'Charlie', 'David']
map 함수의 결과는 앞서도 언급했지만, `map 객체 (map object)` 입니다. 이 객체는 지연 평가(lazy evaluation)를 통해 데이터를 변환하므로, 원본 데이터나 변환된 데이터를 즉시 메모리에 저장하지 않습니다. 대신 필요할 때마다 값을 생성하고 반환합니다.
따라서 `map()` 함수를 사용하여 변환 작업을 정의하고, 그 결과를 리스트로 변환하지 않으면 실제로 계산된 데이터를 확인할 수 없고, 반복문이나 다른 반복 가능한 객체를 사용하여 값을 추출할 때마다 계산이 이루어 집니다.
예를 들어, 다음과 같이 `map() 함수의 결과를 리스트로 변환하지 않고 직접 출력하면 map객체를 확인 할 수 있습니다.
numbers = [1, 2, 3, 4, 5]
squared_numbers = map(lambda x: x ** 2, numbers)
# map 객체를 직접 출력
print(squared_numbers) # 출력: <map object at 0x7f1f38154a90>
리스트 외에도 튜플, 세트 등 다양한 형태로 변환할 수 있습니다.
`map()` 함수와 if 조건문을 함께 사용할 수 있을까요? 결론은 없다 입니다. 하지만, 아래와 같이 lambda 함수와 filter 함수를 이용하여 특정 조건에 따른 값을 변환하거나, 건너 뛸 수 있습니다.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# lambda 함수 내에서 if 조건문 사용
filtered_numbers = map(lambda x: x if x % 2 != 0 else None, numbers)
# None 값을 필터링하여 홀수만 남김
odd_numbers = list(filter(lambda x: x is not None, filtered_numbers))
print(odd_numbers) # 출력: [1, 3, 5, 7, 9]
조금 복잡해 졌지만, 아래와 같이 한 줄로도 표현이 가능합니다.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = list(filter(lambda x: x is not None, map(lambda x: x if x % 2 != 0 else None, numbers)))
print(odd_numbers) # 출력: [1, 3, 5, 7, 9]
다음은 한개 이상의 iterable을 사용하는 방법입니다.
map(function, iterable1, iterable2, ...)
list1 = [1, 2, 3]
list2 = [4, 5, 6]
sum_result = map(lambda x, y: x + y, list1, list2)
# map 객체를 리스트로 변환하여 결과를 얻을 수 있음
sum_result_list = list(sum_result)
print(sum_result_list) # 출력: [5, 7, 9]
위 예제에서 `map()` 함수는 두 개의 리스트 `list1`과 `list2`를 동시에 처리하며, 각 요소를 더하여 새로운 리스트를 생성합니다. 이렇게 여러 개의 `iterable`을 동시에 처리할 때는 각 `iterable`의 요소가 함수에 순서대로 전달되어야 합니다.
여러 개의 iterable을 동시에 처리하려면, function이 여러 개의 인자를 받을 수 있도록 정의해야 합니다. 이렇게 function이 여러 개의 인자를 받는 경우, map() 함수는 각 iterable에서 해당 위치의 요소를 차례대로 function에 전달합니다.
예를 들어, 두 개의 iterable을 동시에 처리하려면 function을 두 개의 인자를 받는 함수로 정의해야 합니다:
두개의 iterable의 요소의 개수는 같도록 정의해야 하겠지만, 개수가 다를 경우 개수가 작은 `iterable`을 기준으로 동작하며, 요소 개수가 많은 `iterable`의 일부는 처리되지 않을 수 있으니, 주의해야 합니다.
list1 = [1, 2, 3]
list2 = [4, 5]
sum_result = map(lambda x, y: x + y, list1, list2)
print(list(sum_reult)) #출력: [5, 7]
위 예에서 `map()` 함수는 더 적은 요소 개수를 가진 `list2`를 기준으로 동작합니다.
'Programming > 파이썬' 카테고리의 다른 글
[Python] Date, Time 관련 함수 정리 (2) | 2024.01.13 |
---|---|
[파이썬] lambda 함수 (0) | 2023.09.10 |
[파이썬] 리스트 컴프리헨션 (0) | 2023.09.10 |