Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Python filter(): กรองข้อมูลใน Sequence ด้วย Function

ฟังก์ชัน filter() ใช้ กรอง (Filter) องค์ประกอบใน Sequence (List, Tuple, Set, Iterator) โดยใช้ Function ที่คืนค่า True/False คืนค่าเป็น Filter Object (Iterator) ที่ต้องแปลงเป็น List/Tuple เพื่อดูผลลัพธ์

ไวยากรณ์

filter(function, iterable)
# function: ฟังก์ชันที่รับ 1 Argument คืนค่า Boolean
# iterable: Sequence ที่ต้องการกรอง

ตัวอย่างพื้นฐาน

1. กรองเลขคู่

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# ใช้ Function
def is_even(n):
    return n % 2 == 0

evens = list(filter(is_even, numbers))
print(evens)  # [2, 4, 6, 8, 10]

# ใช้ Lambda (สั้นกว่า)
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # [2, 4, 6, 8, 10]

2. กรองสตริงที่ขึ้นต้นด้วยตัวอักษรเฉพาะ

words = ["apple", "banana", "apricot", "cherry", "avocado", "blueberry"]

# เริ่มต้นด้วย 'a'
a_words = list(filter(lambda w: w.startswith('a'), words))
print(a_words)  # ['apple', 'apricot', 'avocado']

3. กรอง Dictionary ใน List

people = [
    {"name": "Alice", "age": 25, "city": "Bangkok"},
    {"name": "Bob", "age": 30, "city": "Chiang Mai"},
    {"name": "Charlie", "age": 17, "city": "Phuket"},
    {"name": "Diana", "age": 22, "city": "Bangkok"},
]

# อายุมากกว่า 18
adults = list(filter(lambda p: p['age'] > 18, people))
print(adults)

# อายุมากกว่า 18 และอยู่กรุงเทพ
bkk_adults = list(filter(lambda p: p['age'] > 18 and p['city'] == 'Bangkok', people))
print(bkk_adults)

Filter vs List Comprehension

numbers = range(1, 101)

# filter()
evens_filter = list(filter(lambda x: x % 2 == 0, numbers))

# List Comprehension (Pythonic, เร็วกว่าเล็กน้อย)
evens_comp = [x for x in numbers if x % 2 == 0]

# ผลลัพธ์เหมือนกัน
print(evens_filter == evens_comp)  # True

เมื่อไหร่ใช้ filter()?

  • Function มีอยู่แล้ว (Built-in หรือ Defined แยก)
  • Chain กับ map(), reduce() (Functional Style)
  • Lazy Evaluation (Iterator) - ประหยัด Memory

Advanced: Chaining filter() และ map()

numbers = range(1, 21)

# กรองเลขคู่ -> ยกกำลังสอง -> ผลรวม
result = sum(map(lambda x: x**2, filter(lambda x: x % 2 == 0, numbers)))
print(result)  # 1540 (2^2 + 4^2 + ... + 20^2)

# เทียบกับ List Comprehension
result2 = sum(x**2 for x in numbers if x % 2 == 0)
print(result2)  # 1540

Filter กับ None (Identity Function)

filter(None, iterable) กรองเฉพ่า Truthy Values (ลบ False, 0, None, "", [], {})

mixed = [0, 1, False, 2, '', 3, None, 'hello', [], [1,2], {}]
truthy = list(filter(None, mixed))
print(truthy)  # [1, 2, 3, 'hello', [1, 2]]

Custom Filter Class (Callable Object)

class RangeFilter:
    """Filter ค่าที่อยู่ในช่วง [min_val, max_val]"""
    def __init__(self, min_val, max_val):
        self.min_val = min_val
        self.max_val = max_val
    
    def __call__(self, value):
        return self.min_val <= value <= self.max_val

# ใช้งาน
scores = [45, 67, 89, 23, 90, 78, 56, 34]
pass_filter = RangeFilter(50, 100)
passed = list(filter(pass_filter, scores))
print(passed)  # [67, 89, 90, 78, 56]

Filter ใน Pandas (DataFrame)

import pandas as pd

df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
    'age': [25, 30, 17, 22],
    'score': [85, 92, 78, 88]
})

# Boolean Indexing (Pandas Way - ไม่ใช่ filter())
adults_df = df[df['age'] > 18]
high_scorers = df[df['score'] > 80]

# query() Method
adults_df2 = df.query('age > 18')

สรุป

  • filter(function, iterable) คืนค่า Iterator (Lazy)
  • ใช้ list(), tuple(), set() เพื่อ Materialize
  • Lambda ใช้สำหรับ Simple Conditions
  • List Comprehension มัก Pythonic และเร็วกว่า
  • filter(None, ...) กรอง Truthy Values
  • Pandas ใช้ Boolean Indexing แทน