โจทย์: กำหนดลิสต์ของตัวเลขและค่าเกณฑ์ (Threshold) ตรวจสอบว่า ทุกค่าในลิสต์มากกว่าเกณฑ์หรือไม่ คืนค่า True ถ้าใช่, False ถ้าไม่
ตัวอย่าง
values = [1, 2, 3, 4, 5] threshold = 0 # ทุกค่า > 0 -> True threshold = 1 # มีค่า 1 ไม่ > 1 -> False
วิธีที่ 1: ใช้ all() กับ Generator Expression (Pythonic & Efficient)
แนะนำมากที่สุด - Short-circuit Evaluation (หยุดทันทีเมื่อเจอ False)
def all_greater_than(values, threshold):
return all(value > threshold for value in values)
# ทดสอบ
values = [1, 2, 3, 4, 5]
print(all_greater_than(values, 0)) # True
print(all_greater_than(values, 1)) # False (1 ไม่ > 1)
print(all_greater_than(values, -1)) # True
วิธีที่ 2: ใช้ Loop แบบ Manual (Explicit)
def all_greater_than_loop(values, threshold):
for value in values:
if value <= threshold:
return False
return True
วิธีที่ 3: ใช้ min() (Concise)
def all_greater_than_min(values, threshold):
if not values: # Empty list
return True # Vacuously true
return min(values) > threshold
การจัดการ Edge Cases
def all_greater_than_robust(values, threshold):
# Empty list: Vacuously True (ไม่มีค่าใดที่ขัดแย้ง)
if not values:
return True
# ตรวจสอบ Type
try:
return all(v > threshold for v in values)
except TypeError:
raise TypeError("Elements must be comparable with threshold")
# ทดสอบ Edge Cases
print(all_greater_than_robust([], 5)) # True
print(all_greater_than_robust([5], 5)) # False (5 ไม่ > 5)
print(all_greater_than_robust([5.1], 5)) # True
print(all_greater_than_robust([1, 2, None], 0)) # TypeError
ตัวอย่างการใช้งานจริง
1. Validation: ตรวจสอบอายุขั้นต่ำ
ages = [25, 30, 35, 40, 22]
min_age = 18
if all_greater_than(ages, min_age):
print("ทุกคนอายุมากกว่า 18 ปี - อนุมัติ")
else:
print("มีคนอายุไม่ถึงเกณฑ์")
2. Data Quality: ตรวจสอบค่าที่เป็นบวกทั้งหมด
measurements = [1.2, 3.4, 2.1, 0.5, 4.8]
if all_greater_than(measurements, 0):
print("ค่าทั้งหมดเป็นบวก - ข้อมูลถูกต้อง")
else:
print("พบค่าติดลบหรือศูนย์ - ตรวจสอบข้อมูล")
3. Filter ลิสต์ที่ผ่านเกณฑ์
# หา Sub-lists ที่ทุกค่า > 10
data = [
[11, 12, 13],
[5, 15, 20],
[20, 30, 40],
[10, 11, 12]
]
valid_sublists = [sublist for sublist in data if all_greater_than(sublist, 10)]
print(valid_sublists) # [[11, 12, 13], [20, 30, 40]]
Performance Comparison
import timeit
import random
large_list = [random.randint(1, 100) for _ in range(1_000_000)]
methods = {
"all() + gen": "all(x > 50 for x in large_list)",
"min()": "min(large_list) > 50",
"loop": "all_greater_than_loop(large_list, 50)",
}
for name, code in methods.items():
time = timeit.timeit(code, globals=globals(), number=10)
print(f"{name:15}: {time:.4f}s")
ผลลัพธ์ทั่วไป
all() + gen : 0.4500s (Short-circuit - หยุดเร็วถ้าเจอ False เร็ว) min() : 0.0800s (เร็วที่สุด แต่ต้องวนครบทุกค่าเสมอ) loop : 0.4800s
หมายเหตุ: min() เร็วที่สุดใน Python เพราะเป็น C Implementation แต่ไม่มี Short-circuit
สรุป
- Best Practice:
all(value > threshold for value in values)- อ่านง่าย, Short-circuit, Pythonic - Empty List: คืนค่า
True(Vacuous Truth) - Performance:
min()เร็วสุดสำหรับ True Case,all()เร็วกว่าสำหรับ False Case (Early Exit)