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



ภาษา python เบื้องต้น บทที่ ๑๒: การจัดการกับลิสต์
เขียนเมื่อ 2016/03/05 17:24
ในบทที่ ๘ ได้แนะนำเกี่ยวกับข้อมูลประเภทลำดับของข้อมูลไปแล้ว ซึ่งได้แก่ลิสต์ (list), ทูเพิล (tuple), เรนจ์ (range)

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

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



การกลับลำดับลิสต์
สามารถกลับลำดับของสมาชิกในลิสต์จากหัวมาท้ายได้โดยใช้ for สร้างลิสต์ใหม่ที่ดึงข้อมูลลิสต์เดิมที่ไล่ตำแหน่งจากท้ายมาหัว เช่น
a = ['ก','ข','ค','ง','จ']
b = [a[4-i] for i in range(len(a))]
print(b) # ['จ', 'ง', 'ค', 'ข', 'ก']

อย่างไรก็ตาม มีวิธีที่สามารถสลับลำดับของสมาชิกได้ในทันที นั่นคือใช้เมธอด reverse
a = ['ก','ข','ค','ง','จ']
a.reverse()
print(a) # ได้['จ', 'ง', 'ค', 'ข', 'ก']

วิธีนี้ยังมีข้อดีตรงที่เป็นการเปลี่ยนสลับลำดับของสมาชิกในลิสต์เดิมไปเลยทันที ไม่ต้องสร้างลิสต์ขึ้นมาใหม่ ข้อเสียคือลิสต์แบบเดิมหายไป

นอกจากนี้ยังอาจใช้ฟังก์ชัน reversed อย่างไรก็ตามฟังก์ชันนี้ไม่ได้ให้ผลเป็นลิสต์
a = ['ก','ข','ค','ง','จ']
print(reversed(a)) # ได้ <list_reverseiterator object at 0x10de03198>

จะเห็นว่าผลที่ได้ไม่ใช่ลิสต์ที่ถูกสลับตำแหน่งข้อมูล แต่เป็นออบเจ็กต์อีกชนิดหนึ่งชื่อชนิด list_reverseiterator ซึ่งเป็นอิเทอเรเตอร์ (iterator) ชนิดหนึ่ง เวลาสั่งให้แสดงผลจะไม่สามารถเห็นผลได้ทันที

อย่างไรก็ตามสามารถนำมาใช้ใน for ได้เหมือนกับลิสต์ ละจะเห็นว่าตำแหน่งถูกสลับจากหลังมาหน้าจริงๆ
for i in reversed(['ก','ข','ค','ง','จ']):
    print(i,end=' ')
# ได้ จ ง ค ข ก

หรืออาจเปลี่ยนให้เป็นลิสต์ธรรมดาได้โดย
list(reversed(('ก','ข','ค','ง','จ'))) #ได้ ['จ', 'ง', 'ค', 'ข', 'ก']
วิธีนี้ใช้กับทูเพิลได้เช่นกัน
tuple(reversed(('ก','ข','ค','ง','จ'))) # ได้ ('จ', 'ง', 'ค', 'ข', 'ก')



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

นายพรานสามารถขนหมูป่ากลับได้แค่ตัวเดียว สมมุติว่าเข้าไปถึงเขาเจอหมูป่าตัวหนึ่งก็ฆ่าแล้วขนมา แต่ต่อมาก็เจอตัวใหม่ซึ่งใหญ่กว่า จึงตัดสินใจทิ้งตัวเก่าไป

พอเดินไปต่อก็ฆ่าหมูป่าได้อีกตัว แต่ตัวนี้ตัวเล็กกว่าเขาจึงเดินผ่านไปโดยเก็บตัวเดิมไว้ หลังจากนั้นก็เดินเจอหมูป่าอีกหลายตัวแล้วก็ทำเหมือนเดิมคือถ้าเจอตัวใหญ่ กว่าก็ฆ่าแล้วเปลี่ยนไปถือตัวนั้น

จนสุดท้ายนายพรานก็จะได้หมูป่าตัวใหญ่ที่สุดกลับบ้าน

การหาค่าสูงสุดของลิสต์ก็ใช้หลักการเดียวกันนี้

ลองสร้างลิสต์ของน้ำหนักหมูป่าทั้งหมดในป่าแล้วใช้ for เพื่อไล่หาค่าน้ำหนักของตัวที่มากที่สุดดู
mupa = [50.9,89.3,62.7,101.2,70.4,129.3,94.9] #น้ำหนักหมูป่า 7 ตัว
mmax = mupa[0] # ตั้งค่าสูงสุดเริ่มต้น
i = 0 # ลำดับของค่าสูงสุดเริ่มต้น
for m in mupa: # ทำการวนซ้ำตามจำนวนในลิสต์
    if(m>mmax): # ถ้ามากกว่าค่าสูงสุดเดิม
        mmax = m # ให้เปลี่ยนเป็นค่านั้น
        imax = i # และเปลี่ยนลำดับด้วย
    i += 1
print('ตัวที่ %d หนักสุด หนัก %.1f กก.'%(imax,mmax))

ผลลัพธ์
ตัวที่ 5 หนักสุด หนัก 129.3 กก.

อย่างไรก็ตาม มีฟังก์ชันที่ใช้หาค่าสูงสุดได้ทันที นั่นคือ max
print(max(mupa)) # ได้ 129.3

และในทางกลับกันก็สามารถหาค่าต่ำสุดได้ด้วย โดยใช้ฟังก์ชัน min
print(min(mupa)) # ได้ 50.9

แต่ฟังก์ชันนี้ไม่สามารถบอกลำดับของข้อมูลที่ให้ค่าสูงสุดหรือต่ำสุดได้ ต้องใช้คู่กับฟังก์ชัน index เพื่อหาว่าตัวที่ตำแหน่งไหนมีค่าเป็นค่าสูงสุด
print(mupa.index(max(mupa))) # ได้ 5
หรือเขียนแบบนี้ก็ได้
print(max(mupa, key=mupa.index)) # ได้ 5
การใช้เมธอด index นี้เหมือนกับ index ที่ใช้กับสายอักขระซึ่งอธิบายไปในบทที่แล้ว แต่ลิสต์จะไม่มี rindex และไม่มี find กับ rfind ด้วย



ผลรวมและค่าเฉลี่ยของตัวเลขในลิสต์
หากมีลิสต์ที่ประกอบไปด้วยจำนวนตัวเลข สามารถหาค่ารวมของสมาชิกในลิสต์ทั้งหมดได้โดยใช้ for ไล่สมาชิกทีละตัวแล้วให้บวกไปเรื่อยๆ
x = [124.3,45.4,34.5,199.8,444.3,322.2,401.1]
ruam = 0
for s in x:
    ruam +=s
print(ruam) # ได้ 1571.6

ส่วนค่าเฉลี่ยก็แค่นำความยาวของลิสต์มาหารอีกที
chalia = ruam/len(x)
print('ค่าเฉลี่ยเท่ากับ %.2f'%chalia) # ได้ ค่าเฉลี่ยเท่ากับ 224.51

ในภาษาไพธอนมีฟังก์ชันที่ใช้สำหรับหาค่าผลรวมของลิสต์โดยเฉพาะ คือ sum สามารถใช้เพื่อหาผลรวมและค่าเฉลี่ยได้ดังนี้
print(sum(x)) # ได้ 1571.6
print(sum(x)/len(x)) # ได้ 224.5142857142857



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

ตัวอย่าง หาว่ามี 2 กี่ตัวในลิสต์ w
w = [1,2,1,2,2,2,1,2,2,1,1,1,1,2,1,1,2,2]
nap = 0
for b in w:
    if(b==2): nap += 1
print(nap) # ได้ 9

นอกจากนี้ยังอาจทำได้ง่ายๆโดยใช้เมธอด count เช่นเดียวกับที่ใช้ในสายอักขระ
print(w.count(2)) # ได้ 9



การจัดเรียงลิสต์
วิธีการจัดเรียงสมาชิกในลิสต์ตามลำดับค่ามากน้อยนั้นมีอยู่หลายวิธี แต่วิธีที่เข้าใจง่ายที่สุดและนิยมสอนกันในเบื้องต้นก็คือการเรียงลำดับแบบฟอง (bubble sort) คือตรวจดูค่าแล้วสลับลำดับทีละคู่ไปเรื่อยๆ โดยไล่จากตัวแรกกับตัวที่สอง  ไปตัวที่สองกับตัวที่สาม แล้วไล่ไปเรื่อยๆจนถึงตัวรองสุดท้ายกับตัวสุดท้าย จากนั้นก็วนสลับอย่างนี้ไปอีกเรื่อยๆจนเรียงกันหมด
x = [35,24,30,17,15,6,8,2]
for i in range(len(x)-1): # ทำซ้ำไป len(x)-1 ครั้ง
    for j in range(len(x)-i-1): # ทำซ้ำโดยไล่ตั้งแต่ j เป็น 0 ไปจนถึง j เป็น len(x)-i-2
        if(x[j]>x[j+1]): # ถ้าตัวซ้ายมากกว่าตัวขวาให้สลับ
            x[j],x[j+1] = x[j+1],x[j]
    print(x)

ผลลัพธ์
[24, 30, 17, 15, 6, 8, 2, 35]
[24, 17, 15, 6, 8, 2, 30, 35]
[17, 15, 6, 8, 2, 24, 30, 35]
[15, 6, 8, 2, 17, 24, 30, 35]
[6, 8, 2, 15, 17, 24, 30, 35]
[6, 2, 8, 15, 17, 24, 30, 35]
[2, 6, 8, 15, 17, 24, 30, 35]

อย่างไรก็ตามตามในทางปฏิบัติแล้วมีวิธีอื่นที่เร็วกว่า ตัวอย่างนี้แค่ยกมาเพื่อฝึกกระบวนการคิดเท่านั้น ที่จริงแล้วในไพธอนมีคำสั่งเฉพาะที่ใช้ในการทำให้สมาชิกของลิสต์เรียงกันทันทีโดยง่าย นั่นคือเมธอด sort
x = [35,24,30,17,15,6,8,2]
x.sort()
print(x) # ได้ [2, 6, 8, 15, 17, 24, 30, 35]

ซึ่งจะพบว่านอกจากจะเขียนง่ายกว่าแล้วยังทำงานเร็วกว่ามากอย่างเทียบไม่ติด ดังนั้นในทางปฏิบัติแล้วจึงควรใช้วิธีนี้มากกว่า

หากต้องการเรียงกลับด้านก็เพิ่มคีย์เวิร์ด reverse เข้าไปเป็น reverse=True (หรือใช้ 1 แทน True ก็ได้)
x = [35,24,30,17,15,6,8,2]
x.sort(reverse=1)
print(x) # ได้ [35, 30, 24, 17, 15, 8, 6, 2]

นอกจากนี้ยังอาจใช้ฟังก์ชัน sorted ซึ่งจะคืนค่าลิสต์ที่เรียงแล้ว
x = [35,24,30,17,15,6,8,2]
print(sorted(x)) # ได้ [2, 6, 8, 15, 17, 24, 30, 35]

อนึ่ง ฟังก์ชัน sorted ไม่ได้เป็นการแก้ไขตัวลิสต์แต่เป็นการสร้างลิสต์ใหม่โดยใช้สมาชิกของลิสต์เก่ามาจัดเรียง
ดังนั้นทูเพิลก็สามารถใช้ฟังก์ชัน sorted ได้ แต่ผลที่ไดจะออกมาเป็นลิสต์ ต้องแปลงกลับเป็นทูเพิลอีกที
y = (489,378,112,388,98,14,333)
y = tuple(sorted(y))
print(y) # ได้ (14, 98, 112, 333, 378, 388, 489)



การสร้างคีย์ในการเรียงขึ้นเอง
ในการเรียงนั้นปกติหากเป็นตัวเลขก็จะเรียงตามค่าสูงต่ำ หากเป็นตัวอักษรก็จะเรียงตามลำดับในยูนิโค้ด
แต่ก็สามารถตั้งคีย์ขึ้นมาเองเพื่อใช้เป็นดัชนีในการค้นได้เช่นกัน โดยการเพิ่มคีย์เวิร์ด key ลงไปในฟังก์ชัน sorted
ดัชนีที่ใช้อาจเป็นสายอักขระหรือลิสต์ก็ได้
ตัวอย่าง ลองทำให้อักษรเรียงตามลำดับในแป้นพิมพ์เกษมณีโดยไล่จากแถวบนไปแถวล่าง ซ้ายไปขวา
kedma = 'ภถคตจขชฎพฑธรณนยญบฐลฃฅฟหฆกฏดฌษสศวซงผปฉอฮทมฒฬฝ'
a = ['ก','ข','ค','ฆ','ง','จ','ฉ','ช','ซ']
print(sorted(a,key=kedma.index))

ได้
['ค', 'จ', 'ข', 'ช', 'ก', 'ซ', 'ง', 'ฉ']



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



อ้างอิง
http://docs.python.jp/3/library/stdtypes.html
http://www.tohoho-web.com/python/list.html
http://minus9d.hatenablog.com/entry/2015/01/04/235442
http://kaisk.hatenadiary.com/entry/2014/11/04/232558
http://d.hatena.ne.jp/yumimue/20071218/1197985024
https://ja.wikipedia.org/wiki/バブルソート



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


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

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

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

หมวดหมู่

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

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

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
python
-- numpy
-- matplotlib

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

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



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

  ค้นหาบทความ

  บทความแนะนำ

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

ไทย

日本語

中文