φυβλαςのβλογ
บล็อกของ phyblas



maya python เบื้องต้น บทที่ ๑๑: การทำซ้ำด้วย for
เขียนเมื่อ 2016/03/10 19:10
แก้ไขล่าสุด 2021/09/28 16:42
ในบทที่ ๔ ได้พูดถึงการทำซ้ำโดยใช้คำสั่ง while ไปแล้ว และค้างเอาไว้โดยบอกว่ามีอีกคำสั่งที่ใช้สำหรับการทำซ้ำเช่นกัน นั่นคือ for เราจะมาพูดถึงในบทนี้

for เป็นคำสั่งที่ใช้ในการทำซ้ำได้เช่นเดียวกับ while แต่วิธีการทำงานจะต่างกันไป โดย while จะวนซ้ำภายใต้เงื่อนไขที่สอดคล้องกับที่กำหนด แต่ for จะวนซ้ำเป็นจำนวนที่แน่นอนโดยสัมพันธ์กับขนาดของลิสต์ที่กำหนดให้เป็นฐาน โดยมีตัวแปรหนึ่งคอยรับค่าจากลิสต์และเปลี่ยนแปลงไล่ไปตามลำดับเมื่อวนจน ขึ้นรอบใหม่

โครงสร้างของ for ประกอบด้วย
for ตัวแปรที่เปลี่ยนไปทุกรอบ in ลิสต์ที่ใช้เป็นฐาน:
    คำสั่งที่ต้องการให้วนทำซ้ำ

คำสั่งที่ต้องการให้วนซ้ำนั้นจะต้องขึ้นบรรทัดใหม่แล้วเคาะให้ร่นไปเช่นเดียวกับ while

ตัวอย่างการใช้
c = [2,3,5,7,11,13,17,19] # ลิสต์ของจำนวนเฉพาะ
for s in c:
    mc.polyCube(w=s,h=1,d=s)
    mc.move(0,-s,0)

ในแต่ละรอบ s จะรับค่าจากลิสต์ c มาทีละค่า ทำให้รอบแรกจะมีค่าเป็น 2 ตามด้วย 3 แล้วก็ไล่ไปเรื่อยๆตามลำดับ ผลก็คือจะได้ทรงสี่เหลี่ยมที่มีความกว้างตามเลขที่อยู่ในลิสต์ และอยู่ใต้ลงไปเรื่อยๆ



หากเขียนโดยใช้ while ให้ได้ผลเหมือนกันก็จะต้องเขียนแบบนี้
c = [2,3,5,7,11,13,17,19]
i=0
while(i<8):
    mc.polyCube(w=c[i],h=1,d=c[i])
    mc.move(0,-c[i],0)
    i+=1

ซึ่งจะเห็นว่าในกรณีแบบนี้เขียนด้วย for ดูง่ายกว่าสั้นกว่า

สมาชิกของลิสต์ที่ใช้อาจจะเป็นลิสต์ ในกรณีนี้ตัวแปรที่เอามารับค่าก็จะเป็นลิสต์เช่นกัน เช่น
t = [[2,0,0],[0,2,0],[0,0,2],[-2,0,0],[0,-2,0],[0,0,-2]]
for s in t:
    mc.polyPyramid(ax=s,w=2,ns=4)
    mc.move(s[0],s[1],s[2])

ในกรณีนี้ s จะเป็นลิสต์ [2,0,0] ตามด้วย [0,2,0] แล้วก็ไปต่อเรื่อยๆตามลำดับ



ผลที่ได้จะได้พีรามิด ๖ อันที่หันไปคนละด้าน เช่นเดียวกับตัวอย่างที่เคยลงไปแล้วในบทที่ ๘ ซึ่งตอนนั้นใช้ while เพื่อทำซ้ำ ขอยกมาเพื่อเทียบให้เห็น
t = [[2,0,0],[0,2,0],[0,0,2],[-2,0,0],[0,-2,0],[0,0,-2]]
i=0
while(i<6):
    mc.polyPyramid(ax=t[i],w=2,ns=4)
    mc.move(t[i][0],t[i][1],t[i][2])
    i+=1

จะเห็นว่ายาวกว่า ในขณะที่ใช้ for จะประหยัดบรรทัด และยังเขียนสั้นลงดูกะทัดรัดขึ้นด้วย

นอกจากนี้การไล่สมาชิกของลิสต์ที่มีสมาชิกเป็นลิสต์เรายังอาจจะใช้ตัวแปรมารับค่า เท่ากับจำนวนสมาชิกของลิสต์ย่อย เช่น ในตัวอย่างเดิมนี้อาจเขียนได้เป็น
t = [[2,0,0],[0,2,0],[0,0,2],[-2,0,0],[0,-2,0],[0,0,-2]]
for x,y,z in t:
    mc.polyPyramid(ax=[x,y,z],w=2,ns=4)
    mc.move(x,y,z)

for มักใช้คู่กับฟังก์ชัน range() เพื่อให้มีการวนซ้ำตามจำนวนที่ต้องการโดยมีค่าเพิ่มขึ้นเรื่อยๆ เช่น
for i in range(10):
    mc.polyCube(w=0.5,h=0.5,d=0.5)
    mc.move(i,0,0)

จะได้ผลเป็นลูกบาศก์ตั้งเรียงกัน



การใช้ for ซ้อนหลายชั้นก็ทำได้เช่นเดียวกับ while
for i in range(10):
    for j in range(10):
        for k in range(10):
            mc.polyCube(w=0.5,h=0.5,d=0.5)
            mc.move(i,j,k)



คำสั่ง for นอกจากจะใช้เพื่อการทำซ้ำแล้ว ก็ยังเอามาใช้เพื่อสร้างลิสต์ได้ด้วย
u = [0.1*i for i in range(10)]

การเขียนแบบนี้จะมีความหมายว่าให้ u เป็นลิสต์ที่ประกอบไปด้วย 0.1*i โดยที่ i เป็นสมาชิกใน range(10)

นั่นคือ i มีค่าตั้งแต่ 0 ถึง 9 และค่าของสมาชิกในลิสต์นั้นจะได้จากการเอาค่า i ทั้งหมดมาคูณกับ 0.1

ดังนั้นผลจึงได้ a เท่ากับลิสต์ที่มี 0.1, 0.2 ไปจนถึง 0.9

การสร้างในรูปแบบนี้ยังสามารถใช้สร้างลิสต์ของลิสต์ได้ด้วย ในลิสต์ย่อยอาจมีสมาชิก ๒ ตัว เช่น
u = [[i,j] for i in range(10) for i in range(10)]

หรือเป็นลิสต์ย่อยที่มีสมาชิก ๓ ตัว เช่น
u = [[i,j,k] for i in range(10) for j in range(10) for k in range(10)]

ลองนำมาใช้กับการทำซ้ำเพื่อสร้างลูกบาศก์พันลูกเหมือนตัวอย่างก่อนหน้านี้ จะเห็นว่าสามารถทำได้โดยไม่ต้องเขียนโครงสร้างซ้อนกันหลายๆชั้น
u = [[i,j,k] for i in range(10) for j in range(10) for k in range(10)]
for r in u:
    mc.polyCube(w=0.5,h=0.5,d=0.5)
    mc.move(r[0],r[1],r[2])

นอกจากนี้ยังสามารถใส่ข้อจำกัดเงื่อนไขของสมาชิกในลิสต์ลงไปด้วย if ได้ด้วย เช่น
u = [[i,j,k] for i in range(10) for j in range(10) for k in range(10)
    if (i-5)**2+(j-5)**2+(k-5)**2<25 and (i-5)**2+(j-5)**2+(k-5)**2 >16]
for r in u:
    mc.polyCube(w=0.5,h=0.5,d=0.5)
    mc.move(r[0],r[1],r[2])

แบบนี้จะปรากฏเฉพาะลูกบาศก์ที่อยู่ห่างจากตรงกลางในช่วง 4 ถึง 5 หน่วยเท่านั้น เลยเรียงตัวออกมาใกล้เคียงทรงกลม



จะเห็นว่าการสร้างลิสต์แบบนี้สะดวกมาก หากใช้คล่องแล้วจะทำให้การเขียนโค้ดดูกะทัดรัดรวดเร็วขึ้นมาก



นอกจากนี้ยังสามารถวิธีการนี้ในการสร้างสายอักขระที่มีข้อความเรียงกันอย่างเป็น ระบบ เช่น ถ้าต้องการชื่อไฟล์ข้อมูลบางอย่างของวันที่ประกอบด้วยเลขวันที่เรียงกัน เช่น
u = ['201512%02d.txt'%i for i in range(1,32)]

แบบนี้ u จะเป็นลิสต์ที่ประกอบด้วย '20151201.txt', '20151202.txt' เรียงไปเรื่อยๆจนถึง '20151231.txt'

ค่าของ %02d ที่อยู่ภายในเครื่องหมายคำพูดนี้เป็นโค้ดที่แทนเลขจำนวนเต็มสองหลัก โดยจะถูกแทนด้วยค่า i ทีละตัว

รายละเอียดวิธีการเขียนในรูปแบบนี้ไม่อธิบายในที่นี้แต่อ่านได้จาก https://phyblas.hinaboshi.com/tsuchinoko10

ยกตัวอย่างในการใช้กับมายา เช่นหากมีวัตถุที่มีชื่อเรียงกัน เช่นในตัวอย่างนี้
for i in range(10):
    for j in range(10):
        mc.polyTorus()
        mc.move(3*i,0,3*j)
mc.select(['pTorus%d'%i for i in range(1,101)])

เมื่อพิมพ์ตามนี้จะได้โดนัทมา ๑๐๐ ชิ้น โดยที่ทุกชิ้นถูกเลือกอยู่



ในนี้ ๔ บรรทัดแรกเป็นคำสั่งให้สร้างโดนัทออกมาโดยวางตำแหน่งเรียงกัน เนื่องจากครั้งนี้เราไม่ได้ใส่แฟล็กตั้งชื่อของวัตถุ ดังนั้นชื่อของโดนัทจะถูกตั้งโดยอัตโนมัติ เป็น pTorus ตามด้วยลำดับที่ตั้งแต่ 1 ถึง 100 ดังนั้นในบรรทัดสุดท้ายเราใช้ฟังก์ชัน select() โดยที่ภายในระบุลิสต์ที่ประกอบด้วยชื่อของวัตถุทั้งหมดซึ่งสร้างด้วยวิธี สร้างลิสต์ดังที่อธิบายไป

ชื่อของโหนดที่เก็บรูปทรงของโดนัทก็เป็นตัวเลขเรียงกันในแบบเดียวกัน สามารถใช้วิธีสร้างลิสต์แบบนี้เพื่อเข้าถึงได้เช่นกัน ลองพิมพ์ต่อจากตัวอย่างเมื่อกี้ไปตามนี้
for s in ['polyTorus%d'%i for i in range(1,101)]:
    mc.setAttr(s+'.r',1.5)
    mc.setAttr(s+'.axx',1)
    mc.setAttr(s+'.axy',0.2)
    mc.setAttr(s+'.axz',-1)

เป็นการเปลี่ยนขนาดของโดนัททุกชิ้น พร้อมกับเปลี่ยนแกนเพื่อให้หันเปลี่ยนทิศไปด้วย





ขอจบตัวอย่างการใช้ for เพียงเท่านี้ เท่านี้ก็สามารถประยุกต์ใช้ทำอะไรต่างๆในมายาได้มากมาย และเนื่องจากการใช้ for มักจะเขียนแล้วกะทัดรัดกว่า while ดังนั้นในบทต่อๆจากนี้ไปจะใช้ for เป็นหลักแทน while

แม้ for จะดูแล้วเข้าใจยากกว่า while แต่หากเข้าใจและใช้คล่องแล้วจะสะดวกกว่ามาก

เนื้อหาเกี่ยวกับ for เพิ่มเติมอย่างละเอียดกว่านี้อ่านได้ใน https://phyblas.hinaboshi.com/tsuchinoko09



อ้างอิง

<< บทที่แล้ว      บทถัดไป >>
หน้าสารบัญ


-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python >> mayapython
-- คอมพิวเตอร์ >> 3D >> maya

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
มอดูลต่างๆ
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
ภาษา javascript
ภาษา mongol
ภาษาศาสตร์
maya
ความน่าจะเป็น
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

บทความแต่ละเดือน

2024年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2023年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2022年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2021年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2020年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

ค้นบทความเก่ากว่านั้น

ไทย

日本語

中文