본문 바로가기

python

map과 filter

map & filter

 

map

def pow(n):
		return n ** 2    # n의 제곱 값을 계산해서 반환

st1 = [1, 2, 3]

위에서 정의한 pow 함수와 st1이 참조하는 리스트를 이용해서 다음과 같은 리스트를 만들어보고자 한다.

 

st2 == [1, 4, 9]

위는 st1의 값들을 pow 함수에 넣어서 반환된 값들로 이뤄진 리스트이다. 어떻게 해야 이 리스트를 만들 수 있을까? 먼저 다음과 같은 방법이 있다.

 

st1 = [1, 2, 3]
st2 = [pow(st1[0]), pow(st1[1]), pow(st1[2])]  # 값을 일일이 넣어서 pow 함수 호출

st2 => [1, 4, 9] 

위는 정말 불편한 코드이다. 리스트의 길이가 긴 경우 문제가 될 수 있고, 또 이렇게 일일이 함수를 호출하는 것도 번거로운 일이기 때문이다. 이러한 일을 대신해주는 함수가 있는데 바로 map 함수이다.

 

def pow(n):
		return n ** 2

st1 = [1, 2, 3]
st2 = list(map(pow. st1))    #map은 st1의 값들을 전달하면서 pow를 호출한다.

st2 => [1, 4, 9]

map 함수는 st1에 저장된 값들을 하나씩 전달하면서 pow 함수를 호출해준다. 즉, st1에 저장된 값의수만큼 pow 함수가 호출되며 그것이 map 함수가 하는 일이다. 단 이때 map의 두 번째 전달 대상은 iterable 객체이어야 한다.

 

그럼 이 때 pow 함수가 반환하는 값들을 어떻게 얻을 수 있을까? map은 객체를 하나 반환하는데 그 객체는 iterator 객체이다. 따라서 다음과 같은 방식으로 그 값들을 얻을 수 있다.

 

def pow(n):
		return n ** 2

st = [1, 2, 3]
ir = map(pow, st)
for i in ir:       # ir은 iterator 객체이므로 for 루프에 올 수 있다.
		print(i, end = ' ')

-> 1 4 9

위에서는 map에 리스트를 전달했지만, 다음에서 보이듯이 튜플도 전달 가능하고 문자열도 전달이 가능하다. 즉, iterable 객체이면 무엇이든 전달 가능하다.

 

def db1(e):
			return e * 2

list(map(db1, (1, 3, 4)))    # 튜플 (1, 3, 4) 를 map에 전달
=> [2, 6, 8]

list(map(db1, 'hello'))      # 문자열 'hello'를 map에 전달
=> ['hh', 'ee', 'll', 'll', 'oo']

 

 

filter

filter 함수도 map과 마찬가지로 함수를 인자로 전달받는다. 그리고 이 함수는 값을 걸러내는 기준이 된다. 즉, filter 함수는 값을 걸러내는 기능을 제공하는 함수이다.

 

def is_odd(n):
		return n % 2      # 홀수이면 True

st = [1, 2, 3, 4, 5]
ost = list(filter(is_odd, st))

ost => [1, 3, 5]

filter 함수의 첫 번째 인자는 다음과 같아야 한다.

“True 또는 False를 반환하는 함수”

 

그리고 두 번째 인자는 다음과 같아야 한다.

“리스트나 튜플과 같이 값을 저장하고 있는 iterable 객체”

 

즉, 위 예제에서 filter는 st에 저장된 값을들 하나씩 꺼내서 is_odd에 전달한다. 그리고 is_odd가 True를 반환하는 값들을 따로 모은다. 그리고 이 값들을 얻을 수 있는 iterator 객체를 반환한다.

 

st = list(range(1, 11))
fst = list(filter(lambda n: not(n % 3), map(lambda n: n**2, st)))

fst => [9, 36, 81]

일단 위의 문장에서 map 함수를 호출하는 부분이 먼저 진행된다.

 

map(lambda n: n**2, st)) 을 통해서 리스트 st에 저장된 값을의 제곱에 해당하는 다음 값들이 만들어진다.

1, 4, 9, 16, 25, 36, 49, 64, 81, 100

 

그리고 위의 값들을 하나씩 얻을 수 있는 iterator 객체가 반환되어 다음의 filter 함수 호출이 진행된다. (map이 반환한 iterator 객체를 ir1이라 가정한다.)

fst = list(filter(lambda n: not(n % 3), ir1))

 

위의 filter 함수를 통해서 3의 배수만 통과되고 다음 값들만 남게 된다.

9, 36, 81

 

마지막으로 위의 값들을 하나씩 얻을 수 있는 iterator 객체가 filter 함수 호출의 결과로 반환되어 다음의 상태가 된다.(filter가 반환한 iterator 객체를 ir2이라 가정한다.)

fst = list(ir2)

 

그래서 결국 9와 36과 81로 이뤄진 리스트가 생성되어 변수 fst에 저장된다.

 

윤성우의 열혈 파이썬 중급편을 참고하여 작성되었습니다.

'python' 카테고리의 다른 글

파이썬의 메모리 관리  (0) 2022.04.06
제너레이터 함수  (0) 2022.03.06
리스트 컴프리헨션(2)  (0) 2022.03.02
리스트 컴프리핸션  (0) 2022.01.24
Iterable 객체와 Iterator 객체  (0) 2022.01.24