Tutorial

For-Loop ใน Python ทำงานยังไง?

By Arnon Puitrakul - 17 กุมภาพันธ์ 2022

For-Loop ใน Python ทำงานยังไง?

เรื่องที่น่าสนใจ และ หลาย ๆ คนมองข้ามไปคือเรื่องพื้นฐานมาก ๆ อย่าง For-Loop หรือ Loop อื่น ๆ อย่าง While Loop เราก็ใช้กันบ่อยนะ ใช้กันแทบจะทุกโปรแกรมเลย แต่เราเคยสงสัยกันมั้ยว่า เบื้องหลังของมัน มันทำงานยังไงถึงออกมาให้เราใช้งานได้แบบนี้ โดยของที่ถือว่าเป็น Foundation ในเรื่องนี้คือ Iterable และ Iterator

Iterable

Iterable ถ้าจะให้อธิบายง่าย ๆ คือ Object ที่มีความสามารถในการ Iterate หรือง่ายกว่านั้นอีก คือมันสามารถ Return สมาชิกของมันในแต่ละรอบได้ ถ้าเราเขียน Python มา พวกนี้มันก็คืออะไรก็ตามที่เราสามารถ Loop ใส่มันได้นั่นเอง

>>> iter("Hello World")
<str_iterator object at 0x102b09e20>

>>> iter([1,2,3,4])
<list_iterator object at 0x102b26070>

>>> iter(10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

ตัวอย่างเช่น String ใน Python มันก็จะประกอบด้วย Character หลาย ๆ ตัวต่อกัน การ Iterate ก็คือการที่มันพ่น Character ที่อยู่ใน String ออกมาในแต่ละรอบนั่นเอง ซึ่งถ้า Object ไหนที่เป็น Iterable Object เราสามารถยัดมันใส่ Function ที่ชื่อว่า iter() ได้ จากตัวอย่างสุดท้ายเราจะเห็นว่า มันไม่สามารถ Iterate ได้ เพราะ Integer ไม่ใช่ Iterable Object นั่นเอง

Iterator

>>> hello_iter = iter("Hello World")

>>> next(hello_iter)
'H'

>>> next(hello_iter)
'e'

ณ ตอนนี้เรามี Object ที่สามารถ Iterate ได้แล้ว ก็คือ Iterable แล้วถามว่า ใครจะที่จะเป็นคนไล่รันเอาค่าสมาชิกออกมา สิ่งนั้นก็คือ Iterator มองภาพง่าย ๆ ว่ามันเป็นเครื่องจักรที่เอาค่าออกมา จากใน iter() ตัวมันเอง มันก็ทำอะไรไม่ได้ แต่มันจะเริ่มโยนสมาชิกออกมาก็ต่อเมื่อเราเรียกอีกคำสั่งนึง นั่นคือ next()

>>> next(hello_iter)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

แต่แน่นอนว่าจำนวนสมาชิกมันไม่ได้มีไม่อั้น มันมีจำกัด อย่างใน String "Hello World" ก็มีสมาชิก 11 ตัวด้วยกัน เมื่อเราเรียก next() ไปเรื่อย ๆ จนถึงครั้งที่ 12 ตัว Python จะดัน Exception ออกมาว่าเป็น StopIteration Exception ขึ้นมา ซึ่งเราสามารถเอา Try...Except มาจับได้

>>> list_iter = iter([1,2])
>>> next(list_iter)
1

>>> next(hello_iter)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

เมื่อเรารัน Iterator เพิ่มเข้าไปอีกหนึ่งตัวในโปรแกรม เราจะเห็นว่า Iterator ก็ยังทำงานได้อย่างถูกต้อง โดยเอาอันสมาชิกตัวแรกออกมา และเมื่อเราเรียก Iterator ตัวก่อนหน้าที่มันเรียกจนหมดแล้ว มันก็ยังคงคืน Exception กลับมาเหมือนเดิม จากการทดลองนี้ เราได้ข้อสังเกตว่าแต่ละ Iterator มันก็จะมีการจัดการ State ของใครของมัน ไม่เกี่ยวกับส่วนกลางใด ๆ ทั้งสิ้น

เรื่องนี้เราสามารถอธิบายได้จากวิธีการสร้าง Iterable บน Class โดยที่ Class นั้น ๆ จะเป็น Iterable ได้ มันจะต้องมีการ Implement Dunder Method ที่ชื่อว่า __iter__ ลงไปด้วย แล้วเมื่อเราสร้างออกมาเป็น Object ไม่ว่าเราจะสร้างออกมากี่อัน แต่จะตัว มันก็จะมีการจัดการ State ในตัวของมันเอง เหมือนกับที่เราสามารถใส่ค่าใน Attribute ที่ไม่เหมือนกันได้นั่นเอง

How for-loop works?

หลังจากเราเข้าใจ Concept ของคำว่า Iterable และ Iterator แล้ว เรามาดูคำตอบกันว่าจริง ๆ แล้ว For-Loop เขาทำงานยังไงใน Python เราอยากให้ลองเอาสิ่งที่เราเล่าเมื่อกี้มาคิดดูก่อนว่า มันน่าจะทำอย่างไร ถึงออกมาเป็น For-Loop ได้...... โอเค เฉลย

ขั้นตอนของมันจริง ๆ คือ มันจะแปลง Iterable ให้เป็น Iterator ก่อนผ่านคำสั่ง iter() จากนั้น มันก็จะเรียก next() ของ Iterator ที่สร้างเอาไว้ ทำแบบนี้ไปเรื่อย ๆ จนกว่าจะได้ StopIteration ออกมา มันก็จะออกจาก Loop นั่นเอง อื้อ แค่นั้นเลย....

สรุป

วันนี้เรามาเล่าในหลังม่านการทำงานของ For-Loop ทั้งหลาย ซึ่งมันใช้ 2 ส่วนในการทำให้มันเกิดขึ้นได้คือ Iterable และ Iterator ทำงานเข้าด้วยกัน โดยที่ทั้ง 2 อย่างนี้มีความแตกต่างกัน คือ Iterable คือ Object ที่สามารถ Iterate ได้ ส่วน Iterator เป็นเหมือนเครื่องจักรในการพ่นค่าสมาชิกใน Iterable ออกมานั่นเอง เอาจริง ๆ แล้ว หลาย ๆ คนอาจจะมองว่ามันเป็นเรื่องที่ เออ รู้ทำไมอะ เราว่ามันทำให้เออรู้สึกว่า Python มันเป็นภาษาที่แปลกดีนะ มันใช้วิธีแบบนี้เพื่อให้มันเข้าใจได้ง่าย และ นำไปใช้ได้ง่าย

Read Next...

การสร้าง SSD Storage Pool บน Synology DSM

การสร้าง SSD Storage Pool บน Synology DSM

สำหรับคนที่ใช้ Synology NAS บางรุ่นจะมีช่อง M.2 สำหรับเสียบ NVMe SSD โดยพื้นฐาน Synology บอกว่ามันสำหรับการทำ Cache แต่ถ้าเราต้องการเอามันมาทำเป็น Storage ละ มันจะทำได้มั้ย วันนี้เราจะมาเล่าวิธีการทำกัน...

Multiprogramming, Multiprocessing และ Multithreading

Multiprogramming, Multiprocessing และ Multithreading

หลังจากที่เรามาเล่าเรื่อง malloc() มีคนอยากให้มาเล่าเรื่อง pthread เพื่อให้สามารถยัด Content ที่ละเอียด และเข้าใจง่ายในเวลาที่ไม่นานเกินไป เลยจะมาเล่าพื้นฐานที่สำคัญของคำ 3 คำคือ Multiprogramming, Multitasking, Multiprocessing และ Multithreading...

Synology NAS และ SSD Cache จำเป็นจริง ๆ เหรอ เหมาะกับระบบแบบใด

Synology NAS และ SSD Cache จำเป็นจริง ๆ เหรอ เหมาะกับระบบแบบใด

ใน Synology NAS มีความสามารถนึงที่น่าสนใจคือ การใช้ SSD เป็น Cache สำหรับระบบ ที่ทำให้ Performance ในการอ่านเขียน เร็วขึ้นกว่าเดิมมาก ๆ แน่นอนว่า เราลองละ วันนี้เราจะมาเล่าให้อ่านกันว่า หากใครคิดที่จะทำ มันเหมาะ หรือ ไม่เหมาะกับการใช้งานของเรา...

ฮาวทูย้าย Synology Add-on Package ไปอีก Volume

ฮาวทูย้าย Synology Add-on Package ไปอีก Volume

เรื่องราวเกิดจากการที่เราต้องย้าย Add-on Package ใน DSM และคิดว่าหลาย ๆ คนน่าจะต้องประสบเรื่องราวคล้าย ๆ กัน วันนี้เราจะมาเล่าวิธีการว่า เราทำยังไง เจอปัญหาอะไร และ แก้ปัญหาอย่างไรให้ได้อ่านกัน...