นากกายสีมิ้นต์จัดกล่องเล็กเรียงเป็นแถวบนโต๊ะทำงานสว่าง

Python itertools.batched: หั่นลิสต์เป็นก้อนคงที่แบบสั้น ๆ

น้องกายEngineering

เคยเขียนลูปหั่นลิสต์ทีละ n ชิ้นด้วยสไลซ์เองไหม ผมเคย จนได้ลอง itertools.batched

ตามเอกสารมาตรฐาน batched(iterable, n) คืน iterator ของทูเปิลยาว n จากข้อมูลต้นทาง ถ้าก้อนสุดท้ายสั้นกว่า n จะได้ทูเปิลสั้นกว่า (เว้นแต่ใช้โหมดที่เอกสารรุ่นคุณระบุเป็นแบบเข้ม)

เหมาะกับส่งงานเข้า API ทีละชุด พิมพ์รายงานทีละหน้า หรือแบ่งคิวงานโดยไม่สร้างลิสต์ซ้อนเองทุกครั้ง

import unittest
from itertools import batched


class BatchedTests(unittest.TestCase):
    def test_even_chunks(self):
        self.assertEqual(list(batched([1, 2, 3, 4], 2)), [(1, 2), (3, 4)])

    def test_short_tail(self):
        self.assertEqual(list(batched("ABCDEFG", 3)), [("A", "B", "C"), ("D", "E", "F"), ("G",)])

    def test_n_must_be_positive(self):
        with self.assertRaises(ValueError):
            list(batched([1, 2], 0))


if __name__ == "__main__":
    unittest.main()

ระวัง: n ต้องเป็นจำนวนเต็มบวก และผลเป็นทูเปิล ไม่ใช่ลิสต์ ถ้าต้องการลิสต์ให้ห่อ list(...) เอง

Recap

  • ใช้ batched แทนสไลซ์มือเมื่อต้องการก้อนขนาดคงที่
  • ทดสอบก้อนท้ายที่สั้นกว่า n
  • ตรวจว่า n <= 0 โยน ValueError ตามที่คาด
  • อ่านเอกสารรุ่น Python ของทีมคุณเรื่องพารามิเตอร์เสริมถ้ามี