นากมิ้นต์กางกล่องหลายใบบนโต๊ะไม้แล้วเทของรวมเป็นกองเดียว สื่อถึงการ unpack ใน comprehension

Python 3.15 แตกลิสต์ใน comprehension ได้แล้ว: PEP 798 คืออะไร

น้องกายEngineering

Python 3.15 ออกอย่างเป็นทางการวันที่ 9 ตุลาคม 2026 และหนึ่งในไฮไลต์ภาษาคือ PEP 798 ที่ให้แตกสมาชิกด้วย * และ ** ได้ใน list, set, dict comprehension รวมถึง generator expression (whatsnew) แปลว่าโค้ดที่เคยซ้อน for สองชั้นหรือเรียก itertools.chain อาจย่อได้ชัดขึ้น (PEP 798) หน้าปล่อยรุ่นยืนยันว่า 3.15.0 เป็น stable release (python.org) Real Python สรุปข่าวเดือนตุลาคมว่า 3.15 เลื่อนจากแผนเดิมเล็กน้อยเพราะมี RC3 แก้บั๊กชุดท้ายก่อนปล่อยจริง (Real Python)

สรุป 30 วินาที: เกิดอะไรขึ้น

ก่อนหน้านี้การ unpack ด้วยดาวมีในที่สร้างลิสต์ธรรมดาตาม PEP 448 แต่ใน comprehension ยังทำไม่ได้ PEP 798 ขยายให้ใช้ใน comprehension ได้ เช่น [*L for L in lists] แทน [x for L in lists for x in L] (whatsnew) ชุดและดิกชันนารีก็รองรับ {*s for s in sets} และ {**d for d in dicts} (PEP 798)

ฟีเจอร์นี้อยู่ในกลุ่มไฮไลต์ของ 3.15 คู่กับ lazy imports และ frozendict แต่บทความนี้โฟกัสแค่การ unpack (whatsnew) วันปล่อย stable คือ 9 ต.ค. 2026 (python.org)

ทำไมเรื่องนี้เกี่ยวกับคุณ

ถ้าคุณเขียนสคริปต์รวมไฟล์หลายชีต หรือรวมรายการสินค้าจากหลายร้านในไฟล์ CSV คุณมักเจอ “ลิสต์ของลิสต์” ที่ต้องแบนให้แบนราบครับ เดิมต้องซ้อน for หรือเรียกเครื่องมืออื่น ตอนนี้ลายใหม่สั้นลงและอ่านออกว่ากำลังแตกของออกมา (PEP 798)

นักเรียนที่เพิ่งเรียน comprehension จะเจอตัวอย่างในเอกสารทางการเร็วขึ้น (whatsnew) ส่วนทีมที่ยังล็อก Python 3.14 หรือต่ำกว่าต้องรู้ว่าลายนี้รันบนเครื่องเก่าไม่ได้ — ถ้าแชร์โน้ตบุ๊กให้เพื่อน ต้องบอกเวอร์ชัน

คนที่ดูแลแพ็กเกจบน PyPI อาจไม่ต้องแก้โค้ดทันที เพราะนี่เป็นไวยากรณ์ใหม่ ไม่ได้ทำลายของเก่า (python.org) แต่ถ้าทีมเริ่มใช้ในเมนแล้ว CI ยังเป็น 3.13 จะพังตอนติดตั้ง

ทำงานยังไง

นึกถึงตลาดนัดที่มีร้านย่อยหลายแผง แต่ละแผงมีถุงสินค้าหลายใบ คุณเคยเดินเก็บทีละถุงแล้วเทรวมลงตะกร้าใหญ่ แบบนั้นคือ nested comprehension ส่วนลายใหม่เหมือนมีเครื่องเทถุงอัตโนมัติที่รับ “ถุงทั้งแผง” แล้วเทต่อเนื่องในตะกร้าเดียว (PEP 798)

เอกสาร whatsnew ยกตัวอย่างลิสต์ [[1,2],[3,4],[5]] แล้วได้ [1,2,3,4,5] จาก [*L for L in lists] (whatsnew) กับดิกชันนารี ถ้าคีย์ซ้ำ ค่าหลังเขียนทับค่าก่อนตามพฤติกรรมรวมดิกปกติ ({'a':3,'b':2} จากตัวอย่างในเอกสาร) (whatsnew)

PEP อธิบายแรงจูงใจว่าต้องการทางเลือกตรงๆ แทน nested comprehension และ itertools.chain (PEP 798) async generator expression ก็รองรับแนวเดียวกันตาม whatsnew (whatsnew)

จุดหักมุม: สั้นลงไม่ได้แปลว่าเร็วขึ้นเสมอ

ลายใหม่ช่วยให้อ่านชัด แต่เอกสารไม่ได้สัญญาว่าจะเร็วกว่า nested for ในทุกเคส (PEP 798) จุดหักมุมคือทีมที่รีบ์รีแฟกเตอร์ทั้งโปรเจกต์เพื่อ “ให้ทัน 3.15” อาจได้โค้ดสวยขึ้นโดยไม่ได้วัดเวลา ถ้าจุดร้อนคือ I/O การแตกลิสต์ในหน่วยความจำไม่ใช่คอขวด

อีกมุม: ถ้าสมาชิกในทีมยังอ่าน PEP 448 ไม่คล่อง การเห็นดาวใน comprehension อาจงงกว่า for ซ้อนที่คุ้นมือ (whatsnew)

เรื่องเงิน / ผลกระทบ

ไม่มีค่าลิขสิทธิ์เพิ่มจากฟีเจอร์นี้ครับ Python เป็นภาษาฟรี (python.org) ต้นทุนจริงอยู่ที่เวลาอัปเกรด CI ทดสอบ และสอนทีม ถ้าโปรเจกต์เรียนหรือสตาร์ทอัพเล็ก การรอจน 3.15 มากับอิมเมจ Docker ที่ใช้ประจำถูกกว่าการบังคับทุกเครื่องวันนี้

ข้อมูลที่ยังไม่ชัด และจุดที่แหล่งข่าวพูดไม่ตรงกัน

whatsnew เป็นภาพรวม ส่วน PEP เป็นสเปกเต็ม ถ้ามีรายละเอียด edge case ให้ยึด PEP และชุดทดสอบใน CPython (PEP 798) หน้าปล่อยรุ่นเน้นยอดรวมฟีเจอร์ ไม่ได้ลงตัวอย่าง unpack ยาวเท่า whatsnew (python.org)

ยังไม่ชัดว่าเครื่องมือฟอร์แมต/ลินต์ทุกตัวในระบบนิเวศรองรับไวยากรณ์นี้ครบในวันปล่อยหรือไม่ แหล่งชุดนี้ไม่ได้สำรวจลินต์ทุกเจ้า แปลว่าต้องเช็กเวอร์ชัน Ruff/Black/ty ในโปรเจกต์คุณเอง

แล้วเราควรทำอะไร

ผู้เรียน / คนเขียนสคริปต์

  1. ติดตั้ง Python 3.15 จากหน้าปล่อยทางการแล้วลองตัวอย่างใน whatsnew (python.org)
  2. เทียบ nested comprehension กับลายดาวบนข้อมูลจริงของคุณ ว่าอ่านง่ายขึ้นไหม
  3. อย่าบังคับใช้ดาวถ้าทีมยังอ่านไม่ออก

ทีมโปรเจกต์

  1. ใส่ requires-python ให้ชัดก่อนใช้ไวยากรณ์ใหม่
  2. อัปเดตอิมเมจ CI แล้วรันเทสต์
  3. อ่าน PEP 798 ส่วนแรงจูงใจและข้อจำกัดก่อนรีแฟกเตอร์ใหญ่ (PEP 798)

ผมมองว่า…

ผมมองว่าฟีเจอร์นี้ไม่ใช่ของเล่นโชว์ไวยากรณ์ แต่คือการทำให้ “รวมของจากหลายกล่อง” อ่านตรงกับที่สมองคิด ถ้าทีมคุณยังมีคนใหม่เยอะ การสอน for ซ้อนก่อนแล้วย่อยเป็นดาวทีหลังอาจปลอดภัยกว่า

ปิดท้าย: สิ่งที่ต้องจับตา

จับตาว่าไลบรารีที่คุณใช้ประกาศซัพพอร์ต 3.15 เมื่อไหร่ และลินต์ในโปรเจกต์อัปเดตรับ PEP 798 หรือยัง คุณลองรัน [*L for L in [[1],[2]]] บนเครื่องตัวเองด้วย 3.15 แล้วหรือยัง?

เวลาเขียนโค้ดจริง ผมแนะนำให้เริ่มจากข้อมูลตัวอย่างสั้นๆ ที่คุณรู้จัก แล้วค่อยขยายเป็นไฟล์ใหญ่ ถ้าผลรวมดิกชันนารีมีคีย์ซ้ำ ให้พิมพ์ผลออกมาดูเองว่าค่าไหนเหลือ เพราะเอกสารบอกชัดว่าค่าหลังเขียนทับ (whatsnew) การทดสอบแบบนี้ใช้เวลาไม่กี่นาที แต่กันบั๊กเงียบในรายงานยอดขาย

สำหรับคนที่สอนคอร์ส Python ในไทย การอัปสไลด์ตัวอย่าง comprehension ปีนี้ควรมี脚注ว่าต้องใช้ 3.15 ขึ้นไป ไม่เช่นนั้นนักเรียนที่ติดตั้งจากแพ็กเกจลินุกซ์เก่ายังรันไม่ได้ (python.org) ถ้าคอร์สยังรองรับ 3.12 เป็นเส้นต่ำสุด ให้สอน for ซ้อนเป็นหลัก แล้วเปิดคลิปสั้นโชว์ลายใหม่เป็นของแถม

ทีมที่เขียนไลบรารีสาธารณะควรระวังการใส่ไวยากรณ์ใหม่ในไฟล์ที่ถูก import โดยผู้ใช้เวอร์ชันเก่า เพราะ SyntaxError จะโผล่ตอน import ไม่ใช่ตอนเรียกฟังก์ชัน (PEP 798) วิธีปลอดภัยคือแยกโมดูล optional หรือใช้ไฟล์แยกที่โหลดเฉพาะเมื่อตรวจเวอร์ชันผ่าน

ในงานประมวลผลข้อมูล ลายดาวช่วยให้ pipeline ที่รวมพาร์ติชันหลายไฟล์อ่านรู้เรื่องขึ้น แต่ถ้าแต่ละพาร์ติชันใหญ่ระดับหน่วยความจำเกือบเต็ม การสร้างลิสต์รวมก้อนเดียวอาจไม่เหมาะ equa generator expression แบบ (*L for L in lists) อาจช่วยไล่ทีละชิ้นโดยไม่เก็บทั้งก้อน (whatsnew) ต้องวัดบนข้อมูลจริงของคุณเอง เพราะเอกสารไม่ได้ให้ตัวเลข benchmark ของฟีเจอร์นี้โดยเฉพาะ

เมื่ออัปเกรด อย่าลืมว่า 3.15 มีฟีเจอร์ใหญ่หลายตัวพร้อมกัน การโทษ PEP 798 ทั้งที่พังจากอย่างอื่นจะทำให้ดีบักยาก Real Python เล่าบริบทเดือนนี้ว่ามี RC3 เพราะ lazy imports เป็นหลัก ไม่ใช่เพราะ unpack (Real Python) แยกประเด็นให้ชัดก่อนเปิดทิกเก็ต

ถ้าคุณใช้ typing และลินต์ร่วมด้วย ให้เช็กว่าเวอร์ชันเครื่องมือรู้จักรูปแบบใหม่หรือไม่ แหล่งชุดนี้ไม่ได้ยืนยันตารางซัพพอร์ตครบทุกเครื่องมือ แปลว่าต้องลองในสาขาทดลองก่อนผสมเข้าเมน (PEP 798)

สุดท้ายเรื่องวัฒนธรรมทีม: โค้ดรีวิวควรถามว่า “ลายนี้ช่วยให้อ่านง่ายขึ้นจริงไหม” ไม่ใช่ “ใช้ของใหม่หรือยัง” ถ้าคำตอบคือเพื่อโชว์เวอร์ชัน ควรย้อนกลับไปลายที่ทีมคุ้น

Recap

  • Python 3.15.0 ออก 9 ต.ค. 2026 มี PEP 798
  • ใช้ * / ** ใน comprehension ได้
  • เอกสาร whatsnew + PEP 798 + หน้าปล่อยรุ่นเป็นสามแหล่งหลัก
  • ยังไม่ชัด: ลินต์ทุกเจ้าครบวันแรกหรือไม่
  • ใส่ requires-python ก่อนใช้ในโปรดักชัน
  • แหล่ง: docs.python.org whatsnew, peps.python.org/pep-0798, python.org release