[Python] map & filter, 리스트 컴프리헨션

1 분 소요

1. map

>>> def pow(n):
        return n**2

>>> st1 = [1,2,3]
>>> st2 = [pow(st1[0]), pow(st1[1]), pow(st1[2])]
>>> st2
[1,4,9]
>>> def pow(n):
        return n**2

>>> st1 = [1,2,3]
>>> st2 = list(map(pow, st1))
>>> st2
[1,4,9]

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

>>> def dbl(e):
        return e*2

>>> list(map(dbl, (1,3,4)))
[2,6,8]
>>> list(map(dbl, 'hello'))
['hh','ee','ll','ll','oo']

map에 튜플이나 문자열도 전달이 가능하다. 즉 iterable 객체이면 무엇이든 전달이 가능하다.

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

>>> st1 = [1,2,3]
>>> st2 = [1,2,3]
>>> st3 = list(map(sum,st1,st2))
>>> st3
[2,4,6]

map에 sum함수를 전달했다. sum함수는 매개변수가 두개이므로 두개의 iterable객체를 요구한다. 각 리스트의 같은 위치의 값들을 더해서 결과를 출력한다.

>>> st = ['one','two','three']
>>> rst = list(map(lambda s: s[::-1], st))
>>> rst
['eno','owt','eerht']

map에 별도의 함수를 정의해 전달하는 방식이 아닌 람다식을 기반으로 코드를 작성할 수도 있다.



2. filter

filter 함수는 값을 걸러내는 기능을 제공하는 함수이다.

>>> def is_odd(n):
        return n%2

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

첫번째 인자는 함수를, 두번째 인자는 리스트나 튜플과 같이 값을 저장하고 있는 iterable 객체이다.

>>> st = list(range(1,11))
>>> list(filter(lambda n: not(n%3), st))
[3,6,9]

10이하의 자연수 중에서 3의 배수만 리스트에 담는 코드를 filter와 람다식을 기반으로 작성할 수 있다.

>>> st = list(range(1,11))
>>> list(filter(lambda n: not(n%3), map(lambda n: n**2, st)))
[9,36,81]

1~10의 제곱 중 3의 배수만 리스트로 담는 코드이다. iterable 객체가 와야하는 위치에 iterator 객체가 올 수도 있다.



3. 두함수를 대신하는 리스트 컴프리헨션

리스트 컴프리헨션을 이용하면 map과 filter함수 사용빈도가 줄어든다.

>>> st1 = [1,2,3]
>>> list(map(lambda n: n**2, st1))
[1,4,9]

>>> [n**2 for n in st1]
[1,4,9]
>>> st = [1,2,3,4,5]
>>> list(filter(lambda n: n%2, st))
[1,3,5]

>>> [n for n in st if n%2]
[1,3,5]
>>> st = list(range(1,11))
>>> list(map(lambda n: n**2, filter(lambda n: n%2, st)))
[1,9,25,49,81]

>>> [n**2 for n in st if n%2]
[1,9,25,49,81]

위의 예시에서 보듯이 map에 filter까지 더해지는 상황에서는 확실히 리스트 컴프리헨션 기반의 코드가 더 간결하다.