ทำความเข้าใจกับ filter()
ฟังก์ชัน filter() ใช้สำหรับ "กรอง" ข้อมูลออกจาก iterable โดยจะเก็บเฉพาะข้อมูลที่ตรงตามเงื่อนไขที่กำหนดไว้
หลักการทำงาน:
filter(function, iterable)
- function: ฟังก์ชันที่รับค่าเข้ามาหนึ่งค่า และส่งคืนค่า Boolean (True หรือ False) ถ้าฟังก์ชันนี้คืนค่า True สำหรับข้อมูลนั้น ข้อมูลจะถูกเก็บไว้ ถ้าไม่จะถูกทิ้งไป
- iterable: ข้อมูลที่สามารถวนซ้ำได้ (เช่น list, tuple)
filter() จะส่งคืน iterator object ไม่ใช่ list โดยตรง เพื่อประหยัดหน่วยความจำ หากต้องการดูผลลัพธ์เป็น list ต้องแปลงด้วย list()
ตัวอย่างการใช้งาน:
โค้ด: เลือกทั้งหมด
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# กรองเอาเฉพาะตัวเลขคู่
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(f"ตัวเลขคู่: {even_numbers}")
- จะทำการตรวจสอบว่าเป็นเลขคู่ไหม
ผลลัพธ์
โค้ด: เลือกทั้งหมด
# กรองเอาเฉพาะสตริงที่ไม่ว่างเปล่า
words = ["hello", "", "world", " ", "python"]
non_empty_words = list(filter(lambda s: s.strip(), words))
print(f"คำที่ไม่ว่างเปล่า: {non_empty_words}")
- ไม่เอาคำที่ว่างเปล่าโดยใช้ strip เพื่อตัดคำ แล้วใช้ filter
ผลลัพธ์
โค้ด: เลือกทั้งหมด
# ใช้ None เป็น function เพื่อกรองค่า "falsy"
data = [0, 1, '', 'apple', False, True, None, []]
truthy_values = list(filter(None, data))
print(f"ค่าที่เป็น True: {truthy_values}")
- ใช้ None แทน function เพื่อจับค่า falsy (พวก 0, '', [])
ผลลัพธ์ ทำความเข้าใจกับ reduce()
ฟังก์ชัน reduce() ใช้สำหรับ "รวม" ข้อมูลทั้งหมดใน iterable ให้เหลือเพียงค่าเดียว โดยจะนำฟังก์ชันที่กำหนดไปประยุกต์ใช้กับค่าสองค่าแรกใน iterable จากนั้นนำผลลัพธ์ไปรวมกับค่าถัดไปไปเรื่อยๆ จนกว่าจะหมด iterable
reduce() ไม่ได้เป็น built-in function เหมือน filter() หรือ map() แต่ต้อง import มาจากโมดูล functools
หลักการทำงาน:
reduce(function, iterable[, initializer])
- function: ฟังก์ชันที่รับค่าเข้ามาสองค่า และส่งคืนค่าเดียว ฟังก์ชันนี้จะถูกนำไปใช้แบบสะสม
- iterable: ข้อมูลที่สามารถวนซ้ำได้
- initializer (Optional): ค่าเริ่มต้น
ตัวอย่างการใช้งาน:
โค้ด: เลือกทั้งหมด
from functools import reduce
numbers = [1, 2, 3, 4, 5]
# หาผลรวมของตัวเลขทั้งหมด
sum_of_numbers = reduce(lambda x, y: x + y, numbers)
print(f"ผลรวมของตัวเลข: {sum_of_numbers}")
โค้ด: เลือกทั้งหมด
from functools import reduce
numbers = [1, 2, 3, 4, 5]
# หาผลรวมของตัวเลขทั้งหมด
product_of_numbers = reduce(lambda x, y: x * y, numbers)
print(f"ผลคูณของตัวเลข: {product_of_numbers}")
เราสามารถใช้ filter() และ reduce() ร่วมกันเพื่อประมวลผลข้อมูลที่ซับซ้อนขึ้นได้
ตัวอย่าง
โค้ด: เลือกทั้งหมด
from functools import reduce
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# สามารถเขียนรวมกันในบรรทัดเดียวได้
sum_of_even_numbers_one_line = reduce(lambda x, y: x + y, filter(lambda x: x % 2 == 0, numbers))
print(f"ผลรวมของตัวเลขคู่ : {sum_of_even_numbers_one_line}")
- จะทำการคำนวณส่วน filter ก่อน จากนั้นส่งค่ามาให้ reduce
ผลลัพธ์ เมื่อใดควรใช้:
- filter() เหมาะสำหรับงานที่ต้องการเลือก subset ของข้อมูลตามเงื่อนไขที่เฉพาะเจาะจง
- reduce() เหมาะสำหรับงานที่ต้องการรวมข้อมูลจาก iterable ให้เป็นค่าเดียว (เช่น ผลรวม, ผลคูณ, ค่าสูงสุด/ต่ำสุด) และการคำนวณในแต่ละขั้นตอนขึ้นอยู่กับผลลัพธ์ก่อนหน้า
ประสิทธิภาพ: แม้ว่า filter() และ reduce() มักจะถูกกล่าวถึงว่าเร็วกว่า for loop ในบางกรณี เนื่องจากมีการ implement ด้วย C แต่ในความเป็นจริงแล้ว ความแตกต่างด้านประสิทธิภาพมักไม่สำคัญนักสำหรับ use case ส่วนใหญ่ และความชัดเจนของโค้ดควรเป็นสิ่งสำคัญอันดับแรก
สรุป
filter() และ reduce() เป็นฟังก์ชันที่ช่วยให้เราเขียนโค้ด Python ในรูปแบบ Functional Programming ได้อย่างมีประสิทธิภาพ ช่วยให้โค้ดกระชับขึ้นและบางครั้งก็อ่านง่ายขึ้นสำหรับงานที่เหมาะสม การทำความเข้าใจการทำงานและข้อดีข้อเสียของฟังก์ชันเหล่านี้จะช่วยให้คุณเลือกใช้เครื่องมือที่ถูกต้องในการจัดการข้อมูลในโปรเจคโปรแกรม Python ของคุณ หากใช้ร่วมกับ lambda จะยิ่งเพิ่มความยืดหยุ่นในการประมวลผลข้อมูล อย่างไรก็ตาม ควรใช้ด้วยความระมัดระวังเพื่อไม่ให้โค้ดอ่านยากเกินไปสำหรับผู้อื่นหรือแม้แต่ตัวคุณเองในอนาคต
อ้างอิง
- https://www.mindphp.com/คู่มือ/73-คืออะ ... ออะไร.html
- https://www.mindphp.com/บทเรียนออนไลน์/ ... ction.html
- viewtopic.php?t=116403
- viewtopic.php?t=104258
- viewtopic.php?t=107353