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

Generators ใน Python: yield, Memory Efficient และ Iterator Protocol

Generator เป็นฟังก์ชันพิเศษที่ใช้ yield แทน return คืนค่าทีละตัว (Lazy Evaluation) ประหยัดหน่วยความจำมาก

Generator พื้นฐาน

def generator_thru_iter():
    yield 'xyz'
    yield 246
    yield 40.50

for i in generator_thru_iter():
    print(i)
# xyz
# 246
# 40.5

ใช้ next() แบบ Manual

>> g = generator_thru_iter()
>>> next(g)  # หรือ g.__next__()
'xyz'
>>> next(g)
246
>>> next(g)
40.5
>>> next(g)
StopIteration

ทำไม Generator ประหยัด Memory?

ฟังก์ชันปกติ: สร้าง list ทั้งหมดใน RAM → คืน list

Generator: คืนค่าทีละตัว, เก็บ state (local variables) ไว้ รอ next call

ตัวอย่างจริง: กำลังสองของ 1 ถึง 200,000,000,000

# แบบปกติ: ต้องสร้าง list ขนาด 200B → Out of Memory
n = 200_000_000_000
number_list = range(1, n + 1)  # Python 3 range เป็น lazy แล้ว แต่ loop ยังนาน
for i in number_list:
    print(i * i)

# แบบ Generator: ไม่สร้าง list, คำนวณทีละตัว
def num_generator(n):
    num = 1
    while True:
        yield num
        if num == n:
            return
        num += 1

for i in num_generator(200_000_000_000):
    print(i * i)
    # หยุดได้ทุกเมื่อด้วย Ctrl+C

คุณสมบัติ Generator

  • Defined with def
  • ใช้ yield (หลายครั้งได้)
  • คืน Iterator Object
  • รองรับ Iterator Protocol (__iter__, __next__)
  • Stateful: จำค่าตัวแปรท้องถิ่นระหว่าง yield

Generator Expression (Inline)

>> gen = (x * x for x in range(10))
>>> next(gen)
0
>>> list(gen)
[1, 4, 9, 16, 25, 36, 49, 64, 81]

เมื่อไหร่ควรใช้ Generator?

  • Dataset ใหญ่ / Infinite sequences
  • Pipeline processing (read → transform → write)
  • ต้องการเริ่มใช้ผลลัพธ์ทันที ไม่ต้องรอคำนวณเสร็จ
  • Memory constrained environments