파이썬(Python), filter() 함수를 활용한 간결하고 효율적인 데이터 필터링 기법

728x90

파이썬의 filter() 함수는 이터러블 객체(리스트, 튜플 등)에서

특정 조건을 만족하는 요소만 추출하는 함수형 프로그래밍의 중요한 도구다.

 

  1. 기본 필터링: 숫자 리스트에서 짝수만 필터링하는 기본 사용법
  2. None 필터: falsy 값(0, 빈 문자열, 빈 리스트 등)을 제외한 모든 요소 필터링
  3. 람다 함수 활용: 간단한 익명 함수를 사용하여 필터링 함수를 즉석에서 정의
  4. 객체 리스트 필터링: 사용자 정의 클래스 객체 리스트에서 특정 조건을 만족하는 객체 필터링
  5. 사전(Dictionary) 필터링: 딕셔너리 목록에서 특정 키의 값을 기준으로 필터링
  6. filter와 map 조합: 함수형 프로그래밍 스타일로 데이터 처리 파이프라인 구성
  7. 재사용 가능한 필터 함수: 클로저를 활용하여 매개변수를 갖는 필터 함수 생성
  8. 제너레이터 표현식과 비교: 파이썬에서 비슷한 기능을 구현하는 다른 방법과 비교
  9. 파일 필터링 예제: 실제 사용 사례 - 특정 확장자를 가진 파일만 필터링

filter() 함수는 함수형 프로그래밍 패러다임을 따르는 중요한 도구로, 다음과 같은 특징이 있음.

  • 지연 평가(lazy evaluation): 필요할 때까지 실제 연산을 수행하지 않음
  • 순수 함수(pure function): 함수의 결과가 입력에만 의존하며 부작용이 없음
  • 선언적 프로그래밍: "어떻게" 보다는 "무엇을" 할지 명시
  • 코드 가독성: 복잡한 for 루프 대신 의도를 명확히 표현

또한 filter()는 map(), reduce() 등 다른 함수형 프로그래밍 도구와 함께 사용할 때 더 강력한 데이터 처리 파이프라인 구성 가능

 

# filter() 함수의 다양한 활용 예제

# 1. 기본 필터링 예제
def is_even(n):
    return n % 2 == 0

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = list(filter(is_even, numbers))
print("짝수 필터링:", even_numbers)  # 출력: [2, 4, 6, 8, 10]

# 2. None 필터 예제 (0, "", [], False 등 falsy 값 제외)
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
nonzero_numbers = list(filter(None, numbers))
print("0이 아닌 숫자:", nonzero_numbers)  # 출력: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

mixed_values = [0, 1, "", "hello", [], [1, 2], {}, {"key": "value"}, False, True]
truthy_values = list(filter(None, mixed_values))
print("참 값만 필터링:", truthy_values)  # 출력: [1, 'hello', [1, 2], {'key': 'value'}, True]

# 3. 람다 함수를 사용한 필터링
# 람다를 사용한 홀수 필터링
odd_numbers = list(filter(lambda x: x % 2 == 1, numbers))
print("람다로 홀수 필터링:", odd_numbers)  # 출력: [1, 3, 5, 7, 9]

# 문자열 길이 필터링
words = ["apple", "banana", "kiwi", "strawberry", "fig", "orange"]
short_words = list(filter(lambda word: len(word) <= 5, words))
print("5글자 이하 단어:", short_words)  # 출력: ['apple', 'kiwi', 'fig']

# 4. 객체 리스트 필터링
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __repr__(self):
        return f"Person(name='{self.name}', age={self.age})"

people = [
    Person("Alice", 25),
    Person("Bob", 17),
    Person("Charlie", 30),
    Person("David", 16),
    Person("Eve", 22)
]

# 성인(18세 이상) 필터링
adults = list(filter(lambda person: person.age >= 18, people))
print("성인만 필터링:", adults)

# 5. 사전(Dictionary) 필터링
students = [
    {"name": "Alice", "grade": "A", "passed": True},
    {"name": "Bob", "grade": "C", "passed": True},
    {"name": "Charlie", "grade": "F", "passed": False},
    {"name": "David", "grade": "B", "passed": True},
    {"name": "Eve", "grade": "D", "passed": False}
]

# 합격한 학생만 필터링
passed_students = list(filter(lambda student: student["passed"], students))
print("합격한 학생:", passed_students)

# B 이상 성적을 받은 학생만 필터링
high_grades = list(filter(lambda student: student["grade"] in ["A", "B"], students))
print("우수 성적 학생:", high_grades)

# 6. filter와 map 조합
# 짝수만 필터링한 후 제곱 계산
even_squares = list(map(lambda x: x**2, filter(is_even, numbers)))
print("짝수의 제곱:", even_squares)  # 출력: [4, 16, 36, 64, 100]

# 7. 재사용 가능한 필터 함수
def create_length_filter(max_length):
    """문자열 길이에 따라 필터링하는 함수 생성기"""
    return lambda text: len(text) <= max_length

max_3 = create_length_filter(3)
max_5 = create_length_filter(5)

texts = ["a", "ab", "abc", "abcd", "abcde", "abcdef"]
print("3글자 이하:", list(filter(max_3, texts)))
print("5글자 이하:", list(filter(max_5, texts)))

# 8. 제너레이터 표현식과 비교
# filter 사용
even_filter = list(filter(lambda x: x % 2 == 0, range(10)))
print("filter 결과:", even_filter)

# 제너레이터 표현식 사용
even_generator = list(x for x in range(10) if x % 2 == 0)
print("제너레이터 결과:", even_generator)

# 9. 파일 필터링 예제
import os

# 현재 디렉토리의 Python 파일만 필터링
if os.path.exists("./"):
    files = os.listdir("./")
    python_files = list(filter(lambda f: f.endswith(".py"), files))
    print("Python 파일:", python_files)
728x90