Logo

파이썬의 filter 내장 함수로 데이터 추출하기

함수형 프로그래밍에서 데이터 필터링(filtering) 작업을 할 때 반복문 대신에 함수 호출로 처리하는 경우가 많은데요. 이번 포스팅에서는 파이썬의 filter() 함수를 사용하여 특정 조건을 충족하는 요소만 추출하는 방법에 대해서 알아보겠습니다.

filter 내장 함수

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

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

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

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

실습 데이터 생성

간단한 실습을 위해서 파이썬 인터프리터에서 사용자 5명의 데이터를 사전(dictionary)의 형태로 생성 한 후에 리스트에 담아서 users 변수에 할당하겠습니다.

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

일반 함수로 필터링

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

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

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

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

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

총 사용자 5명 중 남성 사용자 2명만 출력이 되었습니다!

람다 함수로 필터링

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

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

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

결과 데이터 변환

지금까지는 for 루프를 사용하여 filter() 함수가 추출한 데이터를 콘솔에 출력했는데요. 그런데 실제로 코딩을 하다보면 결과 데이터를 리스트나 튜플의 형태로 저장을 해야하는 경우가 많습니다.

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

예를 들어, GMail을 이메일로 사용하는 사용자만 추려내는 filter() 함수의 결과를 출력해보면 다음과 같이 나올 것입니다.

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

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

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

파이썬에서 가장 널리 사용되는 자료형인 리스트(list)에 대해서는 관련 포스팅을 참고바랍니다.

비슷한 방식으로 tuple() 내장 함수를 사용하면 튜플로도 변환할 수 있습니다.

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

여러 개의 데이터를 저장하기 위해서 사용되는 리스트와 튜플의 차이점에 대해서는 관련 포스팅를 참고 바랍니다.

List Comprehension

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

예를 들어, 남성 사용자만 추려내는 코드를 list comprehension을 이용해서 재작성해보겠습니다.

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

list comprehension은 결과값은 역시 리스트 타입이기 때문에, 별다른 타입 변환이 필요없는 것도 이점이 될 수 있겠습니다. 만약에 튜플을 얻고 싶다면 비슷한 방식으로 tuple() 내장 함수만 사용해주면 됩니다.

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

어떤가요? 참 편리하죠? 저는 개인적으로 list comprehension을 더 선호하는데, list comprehension에 대한 호불호가 워낙 갈리다 보니 여기서 줄이겠습니다. 😅

파이썬에서 가장 많이 사용되는 자료형인 리스트(list)에 대해서는 별도 포스팅에서 아주 자세히 다루고 있으니 참고 바랍니다.

전체 코드

본 포스팅에서 제가 작성한 전체 코드는 아래에서 직접 확인하고 실행해보실 수 있습니다.

https://dales.link/vcw

마치면서

이상으로 여러 개의 데이터로 부터 일부의 데이터만 추려낼 때 사용하는 파이썬의 filter() 내장 함수에 대해서 알아보았습니다. 이 유용한 함수가 불필요한 루프를 피하시고 읽고 쉬운 파이썬 코드를 짜시는데 도움이 되었으면 좋겠습니다.