파이썬 filter 내장 함수 사용법 (feat. List Comprehension)
Mar 21, 2020 · 4 min read



filter 내장 함수

파이썬의 내장 함수인 filter()는 여러 개의 데이터로 부터 일부의 데이터만 추려낼 때 사용합니다.
따라서, 여러 개의 데이터를 담고 있는 list나 tuple을 대상으로 주로 사용하는 함수입니다.

사용 방법은 매우 간단한데요… 기본 문법은 다음과 같습니다.

filter(조건 함수, 순회 가능한 데이터)

filter() 함수는 두번째 인자로 넘어온 데이터 중에서 첫번째 인자로 넘어온 조건 함수를 만족하는 데이터만을 반환합니다.

실습 데이터 생성

파이썬 인터프리터에서 다음과 같이 유저 5명의 데이터를 임의로 생성합니다. 5개의 dictionary를 담고 있는 list 입니다.

>>> users = [{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'},
...  {'mail': 'hintoncynthia@hotmail.com', 'name': 'Madison Martinez', 'sex': 'F'},
...  {'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'},
...  {'mail': 'daniel79@gmail.com', 'name': 'Karen Rodriguez', 'sex': 'F'},
...  {'mail': 'ujackson@gmail.com', 'name': 'Amber Rhodes', 'sex': 'F'}]

일반 함수로 필터링

그럼, 실습 데이터를 대상으로 fitler() 함수를 사용해서 먼저 남성 유저들만 추려내보겠습니다.

filter() 함수는 함수를 인자로 받기 때문에, is_man()이라는 함수를 먼저 작성합니다.

>>> def is_man(user):
...     return user["sex"] == "M"
...

이제, is_man() 함수를 첫번째 인자로, users list를 두번째 인자로 던져서 filter() 함수를 호출합니다.

>>> for man in filter(is_man, users):
...     print(man)
...
{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'}
{'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'}

총 유저 5명 중 남성 유저 2명만 출력이 되었습니다!

람다 함수로 필터링

조건 함수의 코드가 긴 경우에는 위와 같이 함수를 선언하는 것이 낫겠지만, 본 예제와 같이 함수가 짧은 경우에는 람다 함수를 사용하면 더욱 간단 명료한 코드를 짤 수 있습니다.

예를 들어, 람다 함수를 이용해서 여성 유저만 출력하는 코드를 작성해보겠습니다.

>>> for woman in filter(lambda u: u["sex"] != "M", users):
...     print(woman)
...
{'mail': 'hintoncynthia@hotmail.com', 'name': 'Madison Martinez', 'sex': 'F'}
{'mail': 'daniel79@gmail.com', 'name': 'Karen Rodriguez', 'sex': 'F'}
{'mail': 'ujackson@gmail.com', 'name': 'Amber Rhodes', 'sex': 'F'}

결과 데이터 변환

지금까지 filter() 함수로 추려진 결과를 콘솔에 출력만 했었는데요.
많은 경우, 결과 데이터를 list나 tuple 타입으로 저장을 해야합니다.

여기서, 많은 분들을 혼란스럽게 하는 부분이 있는데요… filter() 함수는 filter 타입으로 결과를 리턴한다는 점입니다.

예를 들어, GMail을 이메일로 사용하는 유저만 추려내는 filter() 함수의 결과는 다음과 깉이 출력됩니다.

>>> filter(lambda u: u["mail"].endswith("@gmail.com"), users)
<filter object at 0x11132f7c0>

filter() 함수의 결과값을 list로 변환하는 가장 쉬운 방법은 list() 내장 함수를 사용하는 것입니다.

>>> list(filter(lambda u: u["mail"].endswith("@gmail.com"), users))
[{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'}, {'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'}, {'mail': 'daniel79@gmail.com', 'name
': 'Karen Rodriguez', 'sex': 'F'}, {'mail': 'ujackson@gmail.com', 'name': 'Amber Rhodes', 'sex': 'F'}]

마찬가지로 tuple() 내장 함수를 사용하면 tuple로 변환할 수 있습니다.

>>> tuple(filter(lambda u: u["mail"].endswith("@gmail.com"), users))
({'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'}, {'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'}, {'mail': 'daniel79@gmail.com', 'name
': 'Karen Rodriguez', 'sex': 'F'}, {'mail': 'ujackson@gmail.com', 'name': 'Amber Rhodes', 'sex': 'F'})

여러 개의 데이터를 저장하기 위해서 사용되는 list와 tuple의 차이점에 대해서는 관련 포스트를 참고바라겠습니다.

List Comprehension

사실 파이썬에서는 filter() 함수를 사용하는 것보다 더 파이썬답게(pythonic) 데이터를 추려내는 방법이 있습니다.
바로 파이썬의 🌼이라고 불리는 list comprehension을 사용하는 것인데요.

예를 들어, 남성 유저만 추려내는 코드를 list comprehension을 이용해서 재작성 해보면 아래와 같습니다.

>>> [user for user in users if user["sex"] == 'M']
[{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'}, {'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'}]

list comprehension은 결과값은 역시 list 타입이기 때문에, 별다른 타입 변환이 필요없는 것도 이점이 될 수 있겠습니다.
tuple을 얻고 싶다면 마찬가지로 tuple() 내장 함수만 사용해주면 됩니다.

>>> tuple(user for user in users if user["sex"] == 'M')
({'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'}, {'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'})

어떤가요? 저는 대부분의 경우에는 list comprehension을 더 선호하는데, list comprehension에 대한 호불호가 워낙 갈리다 보니 여기서 줄이겠습니다. 😅

마치면서

이상으로 여러 개의 데이터로 부터 일부의 데이터만 추려낼 때 사용하는 파이썬의 filter() 내장 함수에 대해서 알아보았습니다.
이러한 과정을 흔히 데이터 필터링(data filtering)이라고도 하는데요. 함수형 프로그래밍에서는 매우 자주 사용되는 개념이니 잘 이해하시고 활용하셨으면 좋겠습니다.






Engineering Blog  by Dale Seo