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

Python: จับกลุ่มสตริงติดต่อกันในลิสต์ (Group Contiguous Strings)

บทนำ

เมื่อมีลิสต์ผสมประเภทข้อมูล (mixed types) ต้องการจับกลุ่มเฉพาะสตริงที่ติดต่อกัน (contiguous strings) ให้เป็นสับรายการ แล้วคืนลิสต์ที่ผสมระหว่างค่าเดี่ยวและสับรายการสตริง

ตัวอย่างโค้ด


from itertools import groupby

def is_string(elem):
    """ตรวจสอบว่าเป็นสตริงหรือไม่"""
    return isinstance(elem, str)

def group_contiguous_strings(lst):
    """จับกลุ่มสตริงติดต่อกัน yield ผลลัพธ์"""
    for is_str, group in groupby(lst, key=is_string):
        if is_str:
            yield list(group)  # สตริงติดต่อกัน → สับรายการ
        else:
            yield from group   # ไม่ใช่สตริง → yield ตัวเดี่ยว

# ทดสอบ
my_list = [52, 11, 'py', 'th', 'on', 11, 52, 'i', 's', 18, 'f', 'un', 99]
print("ลิสต์ต้นทาง:", my_list)

result = [*group_contiguous_strings(my_list)]
print("ผลลัพธ์:", result)

ผลลัพธ์


ลิสต์ต้นทาง: [52, 11, 'py', 'th', 'on', 11, 52, 'i', 's', 18, 'f', 'un', 99]
ผลลัพธ์: [52, 11, ['py', 'th', 'on'], 11, 52, ['i', 's'], 18, ['f', 'un'], 99]

คำอธิบายการทำงาน

  1. groupby(lst, key=is_string) แบ่งลิสต์เป็นกลุ่มที่ key (True/False) ติดต่อกัน
  2. ถ้า is_str == True: รวมกลุ่มเป็น list แล้ว yield
  3. ถ้า is_str == False: ใช้ yield from yield แต่ละตัวแยกกัน

การประยุกต์: รวมสตริงในกลุ่ม


def group_and_join_strings(lst, separator=''):
    """จับกลุ่มสตริงติดต่อกันและ join รวม"""
    result = []
    for is_str, group in groupby(lst, key=is_string):
        if is_str:
            result.append(separator.join(group))
        else:
            result.extend(group)
    return result

print(group_and_join_strings(my_list))
# [52, 11, 'python', 11, 52, 'is', 18, 'fun', 99]

print(group_and_join_strings(my_list, ' '))
# [52, 11, 'py th on', 11, 52, 'i s', 18, 'f un', 99]

กรณีใช้งานจริง

  • Parse log lines: จับกลุ่มข้อความ error ติดต่อกัน
  • NLP: รวม tokens ที่เป็นคำต่อเนื่อง
  • Data cleaning: รวม string fragments ที่แยกกันเก็บ

ข้อควรระวัง

  • groupby ต้องการข้อมูลที่ "ติดต่อกัน" แล้ว - ไม่ได้จัดกลุ่มค่าที่ไม่ติดกัน
  • yield from ใช้ได้ใน Python 3.3+
  • ฟังก์ชัน key ควรคืนค่าที่ hashable และ consistent

สรุป

ใช้ itertools.groupby ร่วมกับ yield/yield from จับกลุ่มสตริงติดต่อกันได้อย่างมีประสิทธิภาพ โครงสร้างผลลัพธ์คงเหลือค่า non-string เป็นตัวเดี่ยว สตริงติดต่อกันกลายเป็นสับรายการ