φυβλαςのβλογ
บล็อกของ 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)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

ไทย

日本語

中文