2 minute read

본 포스팅은 “윤성우의 열혈 파이썬 중급편” 책 내용을 기반으로 작성되었습니다. 잘못된 내용이 있을 경우 지적해 주시면 감사드리겠습니다.

7-1. Map & Filter

설명 없이 바로 코드부터 들어간다.

def square(n):
    return n ** 2

num = [2, 3, 5]
num_square = list(map(pow, num))
num_square
(결과) [4, 9, 25]

이것만 봐도 map 함수가 어떤 것인지 알 수 있지 않는가?
map 함수는 무엇을 리턴하는 걸까? 다음 코드를 보자.

def square(n):
    return n ** 2

num = [2, 3, 5]
ir = map(square, num)
next(ir)
next(ir)
next(ir)
(결과) 4
     9
     25

보다시피 map 함수는 iterator 객체를 리턴하게 된다!

iterator 객체를 리턴한다는 것은 iterable 객체가 입력으로 들어간다는 것이다.
map 함수의 두번째 인자는 iterable 객체여야 한다.
따라서 리스트 뿐만 아니라, 튜플, 문자열도 두번째 인자로 들어갈 수 있다.

만약 2개의 매개변수를 갖는 함수에 map 함수를 적용하고 싶다면 다음과 같이 코드를 짜보자.

def sum(n1, n2):
    return n1 + n2

num1 = [2, 3, 5]
num2 = [5, 3, 2]
nums_sum = list(map(sum, num1, num2))
nums_sum
(결과) [7, 6, 7]

7-2. map과 람다

앞서 배운 람다와 이번에 배운 map 함수를 동시에 써먹어볼 시간이다. 그 전에 뭐 하나만 보고 가자.
바로 ‘iterable 객체 값 역방향으로 정렬하기’이다!

s = '안녕하세여'
s[ : :-1] # 2를 넣으면 한칸씩 띄어서 출력
[결과] '여세하녕안'

됐다! 이제 map 함수와 람다 함수를 적용해보자!

subject = ['파이썬', '운영체제', '딥러닝'] # 이번년도 상반기 공부할 내용들...
rev_subject = list(map(lambda s: s[ : :-1], subject))
rev_subject
(결과) ['썬이파', '제체영운', '닝러딥']

혹시 ['닝러딥', '제체영운', '썬이파'] 가 나올꺼라 생각했나?

map이 iterator 객체를 리턴한다는 것을 항상 기억하자! iterator 객체를 리턴하면 next 함수를 적용할 때 가장 먼저 ‘파이썬’이 나온다. 이 문자열을 반전시킨다. 그리고 나머지도 똑같이 적용된다 생각하면 금방 이해할 수 있을 것이다!

7-3. Filter

Fileter 함수는 Map 함수와 비슷하다. 차이라면, Map 함수는 함수가 리턴한 값을 그대로 반영하는 반면, Filter 함수는 함수가 True를 리턴한 경우에 대해 iterator 객체 요소 값을 처리한다.

def find_odd(n):
    return n % 2 # 짝수면 0(False) 리턴, 홀수면 1(True) 리턴

num = [1, 2, 3, 4, 5]
ost = list(filter(find_odd, num))
ost
(결과) [1, 3, 5]

보다시피, Filter 함수의 첫번째 인자는 True나 False를 리턴하는 함수가 와야하며, 두번째 인자는 iterable 객체가 와야한다.

마지막 예제는 지금까지 배운 것들을 응용하여, 1~10 중 3의 배수만 골라 제곱을 적용해 리스트에 저장하는 기능을 만들어 보겠다.

nums = list(range(1, 11))
three_squares = list(filter(lambda a: not(a % 3), map(lambda b: b**2, nums)))
three_squares
(결과) [9, 36, 81]

Filter 함수의 경우, True인 값만 리턴하므로 3의 배수인 경우 a % 3 = 0 이 된다. 따라서 not 함수를 주어 True로 반전 시키도록 한다.

7-4. map과 filter를 대신하는 리스트 컴프리헨션

위 예제를 리스트 컴프리헨션으로 나타낼 수 있다!

nums = list(range(1, 11))
three_squares = [n**2 for n in nums if n % 3 == 0]
three_squares
(결과) [9, 36, 81]

뭔가 filter와 map 함수를 동시에 활용한 것보다 더 심플해보인다!

Leave a comment