บทนำ
Flatten nested list ที่มีโครงสร้างลึกและซับซ้อน ให้กลายเป็นลิสต์แบน (flat list) ของ tuples โดยใช้ recursion และ isinstance() ตรวจสอบประเภท
โค้ดต้นฉบับ (Recursive)
def convert_nested_tuple(my_list):
for elem in my_list:
if isinstance(elem, list):
convert_nested_tuple(elem)
else:
my_result.append(elem)
return my_result
my_list = [[[(3, 62)]], [[[(57, 49)]]], [[[[(12, 99)]]]]]
my_result = []
result = convert_nested_tuple(my_list)
print("ผลลัพธ์:", result)
ผลลัพธ์
ผลลัพธ์: [(3, 62), (57, 49), (12, 99)]
ปัญหาของโค้ดต้นฉบับ
- ใช้ global variable
my_result- ไม่ thread-safe, ใช้ซ้ำไม่ได้ - ไม่คืนค่าจาก recursive call
- hard-coded ตัวแปรกลาง
เวอร์ชันปรับปรุง: Pure Function (ไม่มี side effect)
def flatten_nested_tuples(nested_list):
"""Flatten nested list ของ tuples ให้เป็น list ของ tuples"""
result = []
for elem in nested_list:
if isinstance(elem, list):
result.extend(flatten_nested_tuples(elem))
else:
result.append(elem)
return result
# ทดสอบ
my_list = [[[(3, 62)]], [[[(57, 49)]]], [[[[(12, 99)]]]]]
print(flatten_nested_tuples(my_list))
# [(3, 62), (57, 49), (12, 99)]
วิธีทางเลือกอื่นๆ
1. ใช้ itertools.chain (สำหรับ shallow flatten)
from itertools import chain
# แบบ shallow (1 ระดับ)
shallow = list(chain.from_iterable([[1,2], [3,4]]))
# [1, 2, 3, 4]
2. ใช้ more_itertools.collapse (ต้องติดตั้ง)
# pip install more-itertools
from more_itertools import collapse
result = list(collapse(my_list))
# [(3, 62), (57, 49), (12, 99)]
3. Generator version (ประหยัดหน่วยความจำ)
def flatten_gen(nested):
for elem in nested:
if isinstance(elem, list):
yield from flatten_gen(elem)
else:
yield elem
result = list(flatten_gen(my_list))
4. จัดการประเภทข้อมูลหลากหลาย
def flatten_any(nested, target_types=(list, tuple)):
"""Flatten ทุกประเภทที่ระบุ"""
result = []
for elem in nested:
if isinstance(elem, target_types):
result.extend(flatten_any(elem, target_types))
else:
result.append(elem)
return result
# ทดสอบ
mixed = [[1, (2, 3)], [4, [5, 6]], 7]
print(flatten_any(mixed, (list, tuple)))
# [1, 2, 3, 4, 5, 6, 7]
ประสิทธิภาพ
- Recursive: O(n) เวลา, O(d) หน่วยความจำ (d = ความลึก)
- Generator: O(1) หน่วยความจำเพิ่มเติม (ยกเว้น call stack)
- Python recursion limit: ~1000 ระดับ (ปรับได้ด้วย sys.setrecursionlimit)
สรุป
ใช้ recursive function ที่คืนค่า (pure function) แทน global variable รองรับ nested depth ใดๆ สำหรับ production ควรพิจารณา generator หรือ library more-itertools