เรียน Python แล้วต้องลอง itertools: จาก Loop ธรรมดาสู่การคิดแบบ Data-Driven

ถ้าถามว่ามีโมดูลไหนใน Python ที่ถูกประเมินค่าต่ำกว่าความสามารถจริงมากที่สุด itertools น่าจะติดอันดับต้น ๆ

หลายคนรู้จักมันแค่

from itertools import combinations

เอาไว้สุ่มจับคู่ หรือสร้างชุดข้อมูล

แต่เมื่อเริ่มทำระบบจริง ไม่ว่าจะเป็นเกม, AI, Rule Engine, State Machine หรือ Data Processing จะพบว่า itertools ไม่ได้เป็นแค่เครื่องมือช่วยวนลูป

มันคือชุดเครื่องมือที่ช่วยให้เรา "เปลี่ยนวิธีคิด"

จาก

if ...
elif ...
elif ...

ไปสู่

rules[(state, event)]

จาก

for ...
    for ...
        for ...

ไปสู่

product(...)

จาก

current_player = player1
...
current_player = player2

ไปสู่

next(turns)

product(): เครื่องจักรสร้างความเป็นไปได้

หนึ่งในฟังก์ชันที่ผมชอบที่สุดคือ

from itertools import product

สมมติเราทำเกมการ์ด

มี

elements = ["Fire", "Water", "Wind"]
powers = [10, 20, 30]

เราสามารถสร้างการ์ดทุกใบที่เป็นไปได้ด้วย

cards = list(product(elements, powers))

ผลลัพธ์

[
    ('Fire', 10),
    ('Fire', 20),
    ('Fire', 30),
    ('Water', 10),
    ...
]

โดยไม่ต้องเขียน Loop ซ้อนเอง

ทันทีที่เห็นสิ่งนี้ เราจะเริ่มมองข้อมูลเป็น "ชุดคุณสมบัติ" มากกว่า "รายการที่ต้องสร้างทีละชิ้น"

ซึ่งเป็นแนวคิดเดียวกับการสร้างไอเทม RPG, Monster, Skill หรือ Card Game ในโลกจริง


combinations(): สร้าง Deck โดยไม่ต้องคิดเอง

เมื่อมีการ์ดทั้งหมดแล้ว

สมมติเลือก 5 ใบเป็น Deck

from itertools import combinations

all_decks = combinations(cards, 5)

สิ่งที่ได้คือทุก Deck ที่เป็นไปได้

โดยไม่ต้องเขียน Logic สลับตำแหน่งหรือวนลูปหลายชั้น

แนวคิดนี้ใช้ได้กับ

  • จัดทีม

  • เลือกไอเทม

  • สร้าง Loadout

  • วิเคราะห์ความเป็นไปได้ของเกม


cycle(): Turn-Based แบบสวยงาม

หลายคนเขียนระบบ Turn-Based แบบนี้

if current_player == player1:
    current_player = player2
else:
    current_player = player1

แต่ cycle() ทำให้เรื่องนี้กลายเป็น

from itertools import cycle

turns = cycle([
    player1,
    player2
])

current_player = next(turns)

เรียบง่ายมาก

ยิ่งถ้ามี 4 คน

cycle([
    player1,
    player2,
    player3,
    player4
])

ก็ทำงานได้ทันที


itertools ทำให้เห็น Rule มากกว่า Code

ระหว่างคุยเรื่องเกม เราได้ลองสร้างระบบแพ้ทางธาตุ

หลายคนอาจเขียน

if atk == "Fire" and defend == "Wind":
    damage *= 2

elif atk == "Wind" and defend == "Water":
    damage *= 2

แต่พอใช้ Dictionary ร่วมกับ Tuple

advantage = {
    ("Fire", "Wind"): 2,
    ("Wind", "Water"): 2,
    ("Water", "Fire"): 2
}

และเรียก

bonus = advantage.get(
    (atk, defend),
    1
)

สิ่งที่เกิดขึ้นคือ

เราไม่ได้อ่าน "โค้ด"

เราอ่าน "กฎ"

ทันที


Tuple คือ Composite Key

สิ่งที่ทำให้แนวคิดนี้ทรงพลังคือ

Tuple สามารถใช้เป็น Key ของ Dictionary ได้

rules = {
    ("Idle", "Attack"): "Attacking",
    ("Idle", "Move"): "Moving",
    ("Moving", "Stop"): "Idle"
}

แล้ว

state = rules.get(
    (state, event)
)

แทนที่จะมี

if ...
elif ...
elif ...

เต็มไปหมด

โค้ดเหลือแค่การ Lookup

เหมือนเปิดตารางกฎของเกม


เมื่อ Rule กลายเป็น Data

จุดที่น่าสนใจมากคือ

rules = {
    ("Fire", "Wind"): 2,
    ("Water", "Fire"): 2,
}

จริง ๆ แล้วคือ

Rule Engine ขนาดย่อม

เราแยก

  • Logic

  • Rule

ออกจากกัน

Engine ทำหน้าที่แค่

rules.get(key)

ส่วนกฎทั้งหมดเก็บเป็นข้อมูล

ผลคือ

  • เพิ่ม Rule โดยไม่แก้ Code

  • โหลดจาก JSON ได้

  • ให้ Designer ปรับค่าได้

  • อ่านง่ายกว่าการไล่ Call Stack


Data-Driven Design

นี่คือเหตุผลที่หลายระบบสมัยใหม่เริ่มลดการพึ่งพา Polymorphism หนัก ๆ

แทนที่จะมี

class Fireball(Card):
    ...

class Heal(Card):
    ...

class Lightning(Card):
    ...

หลายร้อยคลาส

เราอาจมี

cards = {
    "FIREBALL": {
        "damage": 30
    },

    "HEAL": {
        "heal": 20
    }
}

แล้วให้ Engine กลางจัดการ

ทันใดนั้น

การ์ดใหม่ไม่ต้องสร้างคลาสใหม่

แค่เพิ่มข้อมูล


itertools ไม่ใช่แค่เรื่อง Loop

หลายคนคิดว่า itertools เป็นแค่เครื่องมือช่วยวนลูป

แต่ยิ่งใช้มากขึ้น จะยิ่งพบว่า

มันช่วยเปลี่ยนวิธีคิดจาก

"เขียนขั้นตอน"

ไปเป็น

"อธิบายความสัมพันธ์ของข้อมูล"

จาก

for
if
elif

ไปสู่

product()
combinations()
cycle()

และสุดท้ายกลายเป็น

rules[(condition1, condition2)]

ซึ่งอ่านแล้วเหมือนกำลังเปิดตารางกฎของเกม มากกว่ากำลังอ่าน Source Code

นั่นเป็นเหตุผลที่ itertools ยังคงเป็นหนึ่งในโมดูลมาตรฐานของ Python ที่ผมชอบที่สุด เพราะมันไม่ได้ทำให้โค้ดสั้นลงอย่างเดียว แต่ทำให้โค้ด "คิดเป็นระบบ" มากขึ้นด้วย

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

รับติดตั้งระบบป้ายโฆษณาดิจิตอล Digital Signage ตั้งเวลาทำงานและควบคุมผ่าน Internet ได้

แจกฟรี ระบบแสดงคิวงาน สำหรับร้านนวด สปา หรือ ร้านทำผม

บริการออกแบบ Character Agent สำหรับธุรกิจ

ป้ายดิจิตอลที่โต้ตอบได้