Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Python: แปลง Nested List เป็น Tuple List (Flatten)

บทนำ

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