บทนำ
โค้ดตัวอย่างสาธิตการกรองลิสต์ให้เหลือเฉพาะลำดับที่ "เพิ่มขึ้นหรือเท่ากับ" (non-decreasing) จากค่าแรก แต่โค้ดต้นฉบับมีบั๊ก: เริ่มจาก my_result = [my_list[0]] แล้ววนลูป for elem in my_list รวมตัวแรกอีกครั้ง ทำให้ค่าแรกซ้ำ
โค้ดต้นฉบับ (มีบั๊ก)
my_list = [5, 23, 45, 11, 45, 67, 89, 99, 10, 26, 7, 11]
my_result = [my_list[0]] # เริ่มด้วยค่าแรก: [5]
for elem in my_list: # วนรวมตัวแรกอีกครั้ง!
if elem >= my_result[-1]:
my_result.append(elem)
print(my_result) # [5, 5, 23, 45, 45, 67, 89, 99] ← 5 ซ้ำ 2 ครั้ง
โค้ดที่แก้ไขแล้ว
my_list = [5, 23, 45, 11, 45, 67, 89, 99, 10, 26, 7, 11]
# วิธี 1: เริ่มจากลิสต์ว่าง วนทุกตัว
result = []
for elem in my_list:
if not result or elem >= result[-1]:
result.append(elem)
print("วิธี 1:", result) # [5, 23, 45, 45, 67, 89, 99]
# วิธี 2: เริ่มจากตัวแรก แล้ววนตั้งแต่ตัวที่ 2
result = [my_list[0]]
for elem in my_list[1:]:
if elem >= result[-1]:
result.append(elem)
print("วิธี 2:", result) # [5, 23, 45, 45, 67, 89, 99]
# วิธี 3: List comprehension (ต้องใช้ walrus operator Python 3.8+)
# ไม่ตรงไปตรงมาเพราะต้องอ้างอิงผลลัพธ์ก่อนหน้า
ผลลัพธ์ที่ถูกต้อง
ลิสต์ต้นทาง: [5, 23, 45, 11, 45, 67, 89, 99, 10, 26, 7, 11]
ผลลัพธ์ (non-decreasing): [5, 23, 45, 45, 67, 89, 99]
ความแตกต่าง: Non-Increasing vs Non-Decreasing
| ชื่อ | เงื่อนไข | ตัวอย่างลำดับ |
|---|---|---|
| Non-Decreasing (เพิ่มหรือคงที่) | x[i] >= x[i-1] | 1, 2, 2, 3, 5 |
| Strictly Increasing (เพิ่มอย่างเคร่งครัด) | x[i] > x[i-1] | 1, 2, 3, 4, 5 |
| Non-Increasing (ลดหรือคงที่) | x[i] <= x[i-1] | 5, 4, 4, 3, 1 |
| Strictly Decreasing (ลดอย่างเคร่งครัด) | x[i] < x[i-1] | 5, 4, 3, 2, 1 |
โค้ดครบถ้วน: รองรับทุกโหมด
def filter_monotonic(lst, mode='non-decreasing'):
"""กรองลิสต์ให้เป็น monotonic ตามโหมด"""
if not lst:
return []
result = [lst[0]]
for x in lst[1:]:
if mode == 'non-decreasing' and x >= result[-1]:
result.append(x)
elif mode == 'strictly-increasing' and x > result[-1]:
result.append(x)
elif mode == 'non-increasing' and x <= result[-1]:
result.append(x)
elif mode == 'strictly-decreasing' and x < result[-1]:
result.append(x)
return result
# ทดสอบ
data = [5, 23, 45, 11, 45, 67, 89, 99, 10, 26, 7, 11]
print("Non-decreasing:", filter_monotonic(data, 'non-decreasing'))
print("Strictly increasing:", filter_monotonic(data, 'strictly-increasing'))
print("Non-increasing:", filter_monotonic(data, 'non-increasing'))
สรุป
โค้ดต้นฉบับมีบั๊กทำให้ค่าแรกซ้ำ ให้แก้โดยเริ่มจากลิสต์ว่างหรือวนตั้งแต่ index 1 ฟังก์ชัน filter_monotonic ข้างต้นรองรับ 4 โหมดการกรอง ใช้งานได้หลากหลาย