On this page
Lambda & Higher-Order Functions
มองฟังก์ชันเป็น "ค่า" ที่เก็บใส่ตัวแปร ส่งเข้าฟังก์ชันอื่น และคืนกลับได้
ใน Python ฟังก์ชันเป็น "first-class object" — เก็บใส่ตัวแปร ใส่ใน list ส่งเป็น argument และคืนจากฟังก์ชันได้เหมือนข้อมูลทั่วไป ความเข้าใจนี้คือรากฐานของ decorator และโค้ดสไตล์ functional
ฟังก์ชันเป็นค่า
def shout(text):
return text.upper()
f = shout # เก็บฟังก์ชันใส่ตัวแปร (ไม่มีวงเล็บ = ไม่เรียก)
print(f("hello")) # HELLO
# ใส่ฟังก์ชันใน list ก็ได้
funcs = [str.upper, str.lower, str.title]
for fn in funcs:
print(fn("hello World")) # HELLO WORLD / hello world / Hello Worldlambda — ฟังก์ชันไม่มีชื่อแบบสั้น
lambda คือฟังก์ชันบรรทัดเดียวไม่มีชื่อ เหมาะกับงานสั้น ๆ ที่ส่งเข้าฟังก์ชันอื่น โครงสร้าง: lambda พารามิเตอร์: นิพจน์ (คืนค่านิพจน์อัตโนมัติ)
square = lambda x: x * x
print(square(5)) # 25
add = lambda a, b: a + b
print(add(2, 3)) # 5
# เทียบกับ def ที่ทำเหมือนกัน
def square_def(x):
return x * xsorted(key=...) — ที่ใช้ lambda บ่อยสุด
งานจริงที่ใช้ lambda มากที่สุดคือบอกวิธีเรียงลำดับผ่านพารามิเตอร์ key
people = [
{"name": "Aph", "age": 25},
{"name": "Bee", "age": 19},
{"name": "Cha", "age": 31},
]
# เรียงตามอายุ
by_age = sorted(people, key=lambda p: p["age"])
print([p["name"] for p in by_age]) # ['Bee', 'Aph', 'Cha']
# เรียงหลายเงื่อนไข: ตามอายุ แล้วชื่อ
by_multi = sorted(people, key=lambda p: (p["age"], p["name"]))
# เรียงคำตามความยาว
words = ["banana", "kiwi", "apple"]
print(sorted(words, key=len)) # ['kiwi', 'apple', 'banana']map & filter (และทำไม comprehension มักดีกว่า)
map ใช้ฟังก์ชันกับทุกตัว, filter กรองตามเงื่อนไข — แต่ใน Python นิยม comprehension มากกว่าเพราะอ่านง่ายกว่า ควรรู้จักทั้งคู่
nums = [1, 2, 3, 4, 5]
# map / filter (คืน iterator ต้องครอบ list())
doubled = list(map(lambda x: x * 2, nums))
evens = list(filter(lambda x: x % 2 == 0, nums))
print(doubled) # [2, 4, 6, 8, 10]
print(evens) # [2, 4]
# แบบ comprehension — Pythonic กว่า อ่านง่ายกว่า
doubled = [x * 2 for x in nums]
evens = [x for x in nums if x % 2 == 0]ถ้าเลือกได้ ใช้ comprehension เพราะอ่านง่ายและเป็นสำนวน Python แต่ map/filter ยังมีประโยชน์เมื่อมีฟังก์ชันสำเร็จอยู่แล้ว เช่น map(str, nums) หรือ map(int, lines)
ฟังก์ชันที่รับฟังก์ชัน (Higher-Order)
higher-order function คือฟังก์ชันที่รับฟังก์ชันอื่นเป็น argument หรือคืนฟังก์ชัน — sorted, map, filter ล้วนเป็นแบบนี้ เราเขียนเองได้
def apply_twice(func, value):
return func(func(value))
print(apply_twice(lambda x: x + 3, 10)) # 16 (10+3+3)
print(apply_twice(str.upper, "hi")) # HIสรุปหัวข้อนี้
- ฟังก์ชันเป็นค่า: เก็บใส่ตัวแปร/list, ส่งต่อ, คืนกลับได้
- lambda = ฟังก์ชันสั้นไม่มีชื่อ: lambda args: นิพจน์
- ใช้ lambda บ่อยสุดกับ sorted(key=...) — เรียงหลายเงื่อนไขด้วย tuple
- map/filter ได้ผลเหมือน comprehension แต่ comprehension อ่านง่ายกว่า
1) เรียง list ของ tuple (ชื่อ, คะแนน) ตามคะแนนจากมากไปน้อย 2) ใช้ map แปลง ["1","2","3"] เป็น [1,2,3] 3) ใช้ filter เก็บเฉพาะคำยาวเกิน 3 ตัวอักษร 4) เขียน higher-order function ที่รับฟังก์ชันกับ list แล้ว apply ฟังก์ชันกับทุกตัว