문제의 역사
함수 map()은 함수형 프로그래밍(아직 Lisp에서도)에서 유래되었으며, 그 목적은 시퀀스의 각 요소에 함수를 적용하여 결과가 포함된 새로운 반복 객체를 반환하는 것입니다. Python에서 그것은 생성기 및 목록 표현식이 등장하기 훨씬 이전에 존재했지만, 여전히 널리 사용되고 있으며, 특히 대규모 데이터 처리 파이프라인에서 그렇습니다.
문제
각 컬렉션의 요소를 어떤 규칙에 따라 변경해야 하는 경우, for 루프와 같은 해결책은 신속하게 복잡해지고 읽기 어려워집니다. 목록 표현식과 map()은 의도를 간결하게 표현할 수 있게 합니다. 이와 함께 이러한 접근 방식 간의 차이를 이해하여 올바른 도구를 선택하는 것이 중요합니다.
해결책
map(func, iterable)은 원래 시퀀스의 요소를 함수 func로 변환하는 게으른 반복자를 생성합니다.map 객체가 요소를 즉시 계산하지 않고 게으르게 작동합니다.def square(x): return x * x squares = map(square, [1, 2, 3]) print(list(squares)) # [1, 4, 9]
목록 표현식 [square(x) for x in [1, 2, 3]]은 같은 작업을 하지만 즉시 리스트를 반환하고, 생성기 표현식 (square(x) for x in [1, 2, 3])은 게으른 생성기입니다.
주요 특징:
map()이 Python 3에서 리스트를 반환하나요?
아니요, Python 3부터 map()은 리스트가 아니라 게으른 반복자를 반환합니다. 리스트를 얻으려면 결과를 수동으로 list()로 감싸야 합니다.
res = map(str.upper, ['a', 'b']) print(res) # <map object ...> print(list(res)) # ['A', 'B']
map()을 사용하여 함수 내에서 필터링 조건을 추가할 수 있나요?
아니요, map()은 요소를 필터링하지 않고 단지 변환만 합니다. 필터링을 위해서는 filter() 또는 목록 표현식을 사용해야 합니다:
result = map(str.upper, ['a', 'b', None]) # None이 오면 map은 str.upper(None) 호출 시 오류를 발생시킵니다. # filter는 map 전에 None을 제거하는 데 도움이 됩니다.
map()을 사용하여 두 개의 시퀀스를 동시에 순회할 수 있나요?
네, map()은 임의의 수의 시퀀스를 받을 수 있으며, 변환 함수는 동일한 수의 인수를 받아야 합니다:
x = [1, 2, 3] y = [10, 20, 30] result = map(lambda a, b: a + b, x, y) print(list(result)) # [11, 22, 33]
개발자는 즉시 리스트를 받기를 기대합니다:
mapped = map(abs, [-1, -2, -3]) print(mapped[1]) # TypeError: 'map' 객체는 인덱스 사용이 불가능합니다.
장점:
단점:
필터링을 위해 생성기 표현식을 사용하고 map()을 통해 변환:
nums = range(-5, 6) positives = (x for x in nums if x > 0) sq = map(lambda n: n * n, positives) print(list(sq)) # [1, 4, 9, 16, 25, 36]
장점:
단점: