ในบทที่ ๗ ได้แนะนำวิธีการทำซ้ำด้วย
while
ไปแล้ว ในบทนี้จะพูดถึงอีกวิธีหนึ่ง ก็คือใช้
for
โครงสร้าง for ในขณะที่
while
จะทำซ้ำตามเงื่อนไขที่กำหนดไว้ตอนต้น
for
นั้นมีกลไกในการทำซ้ำที่ต่างกันออกไป
for
เป็นคำสั่งสำหรับให้ทำซ้ำตามจำนวนของข้อมูลซึ่งใช้เป็นฐานในการวนซ้ำ
นั่นคือการจะใช้
for
ได้ต้องใช้คู่กับข้อมูลจำพวกลำดับของข้อมูล เช่น ลิสต์, ทูเพิล, เรนจ์, ฯลฯ
โครงสร้างเป็นดังนี้
for ตัวแปรที่รับค่า in รายการข้อมูลที่เป็นฐาน:
คำสั่งที่ต้องการให้ทำซ้ำ
ตัวอย่าง
for i in [5,6,4]:
print(i)
ผลที่ได้คือ
5
6
4
จะเห็นว่าในตัวอย่างนี้ข้อมูลที่ใช้เป็นฐานนั้นคือลิสต์ที่มีสมาชิก ๓ ตัว ดังนั้นจึงมีการทำซ้ำ ๓ ครั้ง โดยที่ในแต่ละครั้ง
i
จะรับค่าของสมาชิกทีละตัวซึ่งต่างกันไปในแต่ละรอบ จึงแสดงผลค่าที่ต่างไปตามลำดับ
โดยทั่วไปที่เจอบ่อยที่สุด
for
มักใช้คู่กับ
range
for i in range(1,11):
print(i,end=' ')
ได้ผลเป็น
1 2 3 4 5 6 7 8 9 10
บางครั้งก็อาจใช้คู่กับสายอักขระได้อีกด้วย โดยจะวนทำซ้ำโดยใช้ตัวอักษรในสายอักขระนั้นทีละตัวตามลำดับ
for i in 'αβγδεζ':
print(i,end='|')
ได้
α|β|γ|δ|ε|ζ|
ความหมายของ in in
นอกจากจะใช้คู่กับ
for
แล้วโดยปกติยังใช้เพื่อหาว่าข้อมูลตัวหนึ่งเป็นสมาชิกในลำดับข้อมูลหรือไม่ เช่น
1 in [1,2,3] # ได้ True
10 in range(2,9) # ได้ False
ต้องระวังว่า
in
มี ๒ ความหมายซึ่งแตกต่างกันระหว่างใช้กับ
for
และใชักับ
if
if a in x
หมายถึงตรวจเงื่อนไขว่า a
อยู่ใน x
หรือเปล่า ถ้ามีก็ทำ ถ้าไม่มีก็ไม่ทำ
for a in x
หมายถึงทำซ้ำสำหรับ a
ที่มีค่าเป็นแต่ละตัวใน x
for ซ้อน for for
ก็เช่นเดียวกับ
while
หรือ
if
สามารถซ้อนกันหลายๆชั้นได้
ตัวอย่าง
for i in range(1,7):
for j in range(i-1):
print(i-j,end=' ')
print(1)
ผลลัพธ์
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
6 5 4 3 2 1
ลองดูตัวอย่างการประยุกต์ใช้อีกอันที่ซับซ้อนขึ้นหน่อย ลองสร้างสามเปลี่ยมปัสกาล
pascal = [[1]]
for i in range(1,8):
p = [1]
for j in range(1,i):
p += [pascal[i-1][j]+pascal[i-1][j-1]]
p += [1]
pascal += [p]
print(pascal)
ผลที่ได้
[[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1],
[1, 5, 10, 10, 5, 1],
[1, 6, 15, 20, 15, 6, 1],
[1, 7, 21, 35, 35, 21, 7, 1]]
การสร้างลิสต์จาก for for
นอกจากจะใช้เพื่อสร้างวงจรทำซ้ำแล้ว ยังสามารถใช้เพื่อสร้างลิสต์ได้ด้วย
h = [9-x for x in range(9)]
print(h)
ลิสต์
h
ในที่นี้หากให้เปรียบเทียบเป็นเซ็ตทางคณิตศาสตร์ก็อาจถูกเขียนเป็น
หรือ
ซึ่งเราสามารถทำลิสต์ในลักษณะนี้ได้ง่ายๆด้วยการใช้
for
อย่างที่เห็น
หากไม่ใช้
for
ในลักษณะนี้ จะใช้
for
เพื่อวนซ้ำเพิ่มสมาชิกก็ได้
h = []
for x in range(9):
h.append(9-x)
print(h)
จะเห็นว่าทำแบบนี้ยาวกว่า ดังนั้นการใช้
for
ภายในลิสต์จึงเหมือนเป็นการเขียนย่อให้สั้นลง และนอกจากนี้แล้วยังสร้างได้เร็วขึ้นด้วย
การใช้ if ร่วมกับ for ในการสร้างลิสต์ การสร้างลิสต์ด้วย
for
อาจใช้ร่วมกับ
if
เพื่อคัดกรองเฉพาะบางส่วนที่ต้องการ เช่น
k = [x for x in range(8,33,2) if(x%10!=0)]
print(k) # ได้ [8, 12, 14, 16, 18, 22, 24, 26, 28, 32]
จะเห็นว่า
if
ทำการคัดกรององค์ประกอบที่หาร
10
ลงตัวออกไป
อาจใช้เพื่อคัดกรององค์ประกอบที่มีอยู่ใน ๒ ลิสต์พร้อมกัน เช่น
x = [i**2 for i in range(1,21)]
y = [i for i in range(1,401,3)]
z = [i for i in x if(i in y)]
print(z) # ได้ [1, 4, 16, 25, 49, 64, 100, 121, 169, 196, 256, 289, 361, 400]
ตัวอย่างนี้ทำการสร้างลิสต์
x
และ
y
มาก่อน โดยลิสต์
x
มีค่าเลขจำนวนเต็มยกกำลังสองตั้งแต่
1
ไปถึง
20
ส่วน
y
มีจำนวนที่หาร
3
แล้วได้เศษ
1
ตั้งแต่
1
จนถึง
400
จะได้ว่า
z
ได้สมาชิกเป็นจำนวนที่มีอยู่ในทั้งลิสต์
x
และ
y
คือเป็นเลขยกกำลังสองที่หาร 3 แล้วได้เศษ 1
ลักษณะการเขียนอาจดูแล้วเข้าใจยากสักหน่อย แต่เมื่อใช้คล่องแล้วจะทำให้การสร้างลิสต์ยืดหยุ่นเรียบง่ายขึ้นเป็นอย่างมาก
for
อาจใช้เพื่อสร้างสิ่งที่คล้ายๆกับคู่อันดับหรือฟังก์ชันทางคณิตศาสตร์ได้ เช่น
z = [[i,i**2] for i in range(5)]
print(z) # ได้ [[0, 0], [1, 1], [2, 4], [3, 9], [4, 16]]
for ซ้อน for ในการสร้างลิสต์ ในการสร้างลิสต์อาจใช้
for
มากกว่าหนึ่งด้วย ซึ่งในกรณีนั้นจะเกิดผลลัพธ์เป็นสมาชิกในลิสต์จำนวนมากมายเท่ากับจำนวนของ สมาชิกในลิสต์ที่นำมาใช้เป็นฐานคูณกัน เช่น
ลองใช้
for
สร้างลิสต์ของคู่อันดับที่จับเอาสมาชิกจาก ๒ ลิสต์มาไขว้กันให้หมด
x = range(5)
y = [4-i for i in range(5)]
z = [(i,j) for i in x for j in y] # ได้ [(0, 4), (0, 3), (0, 2), (0, 1), (0, 0), (1, 4), (1, 3), (1, 2), (1, 1), (1, 0), (2, 4), (2, 3), (2, 2), (2, 1), (2, 0), (3, 4), (3, 3), (3, 2), (3, 1), (3, 0), (4, 4), (4, 3), (4, 2), (4, 1), (4, 0)]
หรืออาจสร้างจำนวนที่เป็นผลคูณของสองตัว
z = [i*j for i in x for j in y]
print(z) # ได้ [0, 0, 0, 0, 0, 4, 3, 2, 1, 0, 8, 6, 4, 2, 0, 12, 9, 6, 3, 0, 16, 12, 8, 4, 0]
ผลลัพธ์จะเห็นว่าเป็นการแจกแจงผลคูณของสมาชิกในลิสต์
x
และ
y
ทั้งหมด ทำให้ได้สมาชิกออกมา 25 ตัว
จะเห็นว่าการไล่ซ้ำจะเริ่มจาก
for
ที่อยู่ทางขวา แล้วค่อยตามด้วย
for
ตัวซ้าย
หากลองตัดส่วนที่เกี่ยวข้องกับตัวแปรที่ไล่ค่าในลิสต์ตัวขวาออก จะได้ค่าเท่ากันซ้ำๆ
z = [i for i in x for j in y]
print(z) # ได้ [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4]
กรณีนี้แม้ลิสต์
y
จะไม่ได้ส่งผลต่อค่าของสมาชิกในลิสต์ แต่จำนวนสมาชิกของ
y
ก็มีผลต่อจำนวนที่จะได้ซ้ำ
ดังนั้นวิธีนี้อาจใช้เพื่อทวีคูณจำนวนสมาชิกในลิสต์
f = ['ก','ข','ค','ง']
g = [i for i in f for j in [0,0,0]]
print(g) # ได้ ['ก', 'ก', 'ก', 'ข', 'ข', 'ข', 'ค', 'ค', 'ค', 'ง', 'ง', 'ง']
ตัวแปรระหว่างนอกและใน for ขณะที่สร้างลิสต์ขึ้นด้วย
for
นั้น ต้องมีตัวแปรหนึ่งมาทำหน้าที่เป็นตัวช่วยไล่เพื่อป้อนค่าให้กับลิสต์ ตัวแปรนั้นจะใช้ชื่อว่าอะไรก็ได้ แม้ว่าจะซ้ำกับชื่อที่มีอยู่แล้วก็ไม่มีผลอะไร
i = 100
x = [i for i in range(10)]
print(i) # ได้ 100 เท่าเดิม
จากตัวอย่างนี้จะเห็นว่า
i
ที่ถูกใช้วิ่งในลิสต์ไม่ได้เกี่ยวข้องอะไรกับ
i
ที่ถูกประกาศก่อนหน้า ดังนันพอหาค่า
i
หลังจากสร้างลิสต์จบ ค่าของ
i
ก็ยังคงได้
100
เท่าเดิม
***สำหรับไพธอน 2 ค่า
i
จะเปลี่ยนไปด้วย
>>> รายละเอียด อย่างไรก็ตาม กรณีที่ใช้
for
เพื่อสร้างวงจรทำซ้ำ ตัวแปรที่ถูกใช้จะเปลี่ยนค่าไปด้วย ต่างกับกรณีใช้
for
สร้างลิสต์
i = 100
x = []
for i in range(10):
x.append(i)
print(i) # ได้ 9
จะเห็นว่ากรณีนี้
i
กลายเป็น
9
ซึ่งเป็นค่าสุดท้ายของเรนจ์ที่ถูกไล่ในวงจร
for
แทนที่จะเป็นค่าเดิมคือ
100
สรุปเนื้อหา for
สามารถใช้เพื่อทำการวนซ้ำได้ โดยมีกลไกและข้อดีและข้อเสียต่างไปจาก
while
หากแยกแยะใช้ ๒ วิธีนี้สลับกันไปตามสถานการณ์น่าจะช่วยให้การทำงานมีประสิทธิภาพเป็นอย่างมาก
นอกจากนี้
for
ยังสามารถใช้สร้างลิสต์ได้ด้วย ซึ่งเป็นวิธีการที่สะดวก ช่วยให้การสร้างลิสต์เขียนสั้นลงดูง่ายขึ้นมาก
อ้างอิง