φυβλαςのβλογ
phyblas的博客



การใช้ collections.OrderedDict ใน python
เขียนเมื่อ 2019/07/06 18:42
แก้ไขล่าสุด 2024/02/22 10:43
ในบทเรียนไพธอนเบื้องต้นได้อธิบายถึงเรื่อง dict (ดิกชันนารี) เอาไว้ https://phyblas.hinaboshi.com/tsuchinoko14

ไพธอนก่อนถึงเวอร์ชัน 3.6 นั้นข้อมูลประเภท dict จะไม่มีการเรียงลำดับคีย์ ไม่สนลำดับก่อนหลังในการใส่ข้อมูลเข้าไป คล้ายกับ set (เซ็ต)

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

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

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

ในนี้เรามาดูกันว่า OrderedDict ต่างจาก dict ธรรมดายังไง



วิธีใช้งาน

OrderedDict อยู่ในมอดูล collections ซึ่งเป็นมอดูลมาตรฐานของไพธอน การจะใช้จำเป็นต้อง import เข้ามาก่อน
from collections import OrderedDict

mu = OrderedDict()
mu['นิโกะ'] = 154
mu['อุมิ'] = 159
mu['มากิ'] = 161
print(mu) # ได้ OrderedDict([('นิโกะ', 154), ('อุมิ', 159), ('มากิ', 161)])
print(mu['มากิ']) # ได้ 161
print(list(mu)) # ได้ ['นิโกะ', 'อุมิ', 'มากิ']

จะเปลี่ยนป็นดิกธรรมดาหรือเปลี่ยนกลับก็ได้
print(dict(mu)) # ได้ {'นิโกะ': 154, 'อุมิ': 159, 'มากิ': 161}

เมธอด keys values items ก็ได้ผลเหมือนกับ dict ธรรมดา แต่ชนิดข้อมูลที่ได้จะเป็น odict_keys, odict_values, odict_items
print(mu.keys()) # ได้ odict_keys(['นิโกะ', 'อุมิ', 'มากิ'])
print(mu.values()) # ได้ odict_values([154, 159, 161])
print(mu.items()) # ได้ odict_items([('นิโกะ', 154), ('อุมิ', 159), ('มากิ', 161)])

เพียงแต่คุณสมบัติโดยทั่วไปก็เหมือน dict_keys, dict_values, dict_items ของ dict ธรรมดา



การเปรียบเทียบค่าในดิกชันนารี

ปกติเวลาเอา dict สองอันมาเปรียบเทียบกันด้วยเครื่องหมาย == ว่าเท่ากันหรือเปล่า ขอแค่สมาชิกที่คีย์เดียวกันมีค่าเท่ากันตรงกันหมดก็ถือว่าเท่ากันแล้ว
mu1 = {}
mu1['เอริ'] = 157
mu1['โฮโนกะ'] = 162
mu1['ฮานาโยะ'] = 156
mu2 = {}
mu2['ฮานาโยะ'] = 156
mu2['เอริ'] = 157
mu2['โฮโนกะ'] = 162
print(mu1) # ได้ {'เอริ': 157, 'โฮโนกะ': 162, 'ฮานาโยะ': 156}
print(mu2) # ได้ {'ฮานาโยะ': 156, 'เอริ': 157, 'โฮโนกะ': 162}
print(mu1==mu2) # ได้ True

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

แต่สำหรับ OrderedDict นั้นลำดับมีความสำคัญ นั่นหมายความว่าเมื่อนำ OrderedDict สองอันมาเปรียบเทียบกันด้วยเครื่องหมาย == ว่าเท่ากันหรือเปล่า ผลที่ได้จะเท่ากันก็ต่อเมื่อเหมือนกันทั้งลำดับด้วย
mu1 = OrderedDict()
mu1['เอริ'] = 157
mu1['ฮานาโยะ'] = 156
mu1['โฮโนกะ'] = 162
mu2 = OrderedDict()
mu2['โฮโนกะ'] = 162
mu2['ฮานาโยะ'] = 156
mu2['เอริ'] = 157
print(mu1) # ได้ OrderedDict([('เอริ', 157), ('ฮานาโยะ', 156), ('โฮโนกะ', 162)])
print(mu2) # ได้ OrderedDict([('โฮโนกะ', 162), ('ฮานาโยะ', 156), ('เอริ', 157)])
print(mu1==mu2) # ได้ False
print(dict(mu1)==dict(mu2)) # ได้ True



เมธอด move_to_end

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

mu = OrderedDict([('โคโตริ', 159), ('โนโซมิ', 159), ('ริง', 155)])
mu.move_to_end('โคโตริ')
print(mu) # ได้ OrderedDict([('โนโซมิ', 159), ('ริง', 155), ('โคโตริ', 159)])
mu.move_to_end('ริง',0)
print(mu) # ได้ OrderedDict([('ริง', 155), ('โนโซมิ', 159), ('โคโตริ', 159)])

ถ้าใส่ False (หรือ 0) ก็จะเป็นการย้ายไปไว้หน้าสุด



เมธอด popitem

popitem เป็นเมธอดที่เอาไว้ใช้เอาสมาชิกตัวสุดท้ายออกจากดิกชันนารี พร้อมทั้งคืนค่าที่โดนเอาออกมา
dic = {'ก':76, 'ข':58, 'ค':80}
print(dic.popitem()) # ได้ ('ค', 80)
print(dic) # ได้ {'ก': 76, 'ข': 58}

อย่างไรก็ตาม เมธอดนี้เมื่อใช้กับ OrderedDict จะสามารถเลือกเอาสมาชิกตัวแรกออกได้ โดยใส่ค่า False (หรือ 0)
odadic = OrderedDict({'ง':88, 'จ':60, 'ช':84})
print(odadic.popitem()) # ได้ ('ช', 84)
print(odadic) # ได้ OrderedDict([('ง', 88), ('จ', 60)])
print(odadic.popitem(0)) # ได้ ('ง', 88)
print(odadic) # ได้ OrderedDict([('จ', 60)])



การใช้กับฟังก์ชัน reversed

reversed เป็นฟังก์ชันที่ปกติใช้กับลิสต์ ทำให้สมาชิกภายในลิสต์กลับลำดับจากท้ายมาหน้าเวลาที่มีการวนซ้ำ

รายละเอียดเพิ่มเติมอ่านได้ใน https://phyblas.hinaboshi.com/tsuchinoko12

แต่ว่านอกจากลิสต์แล้วออบเจ็กต์ที่บรรจุข้อมูลเป็นกลุ่ม ชนิดอื่นๆที่มีนิยามเมธอด __reversed__ เอาไว้ก็สามารถใช้ฟังก์ชัน reversed ได้เช่นกัน

กลไกการทำงานจริงๆคือ reversed คือมันจะไปเรียกเมธอด __reversed__ ซึ่งถูกนิยามเอาไว้ภายในคลาสที่สามารถใช้ได้

ดังนั้นพวกออบเจ็กต์ที่ไม่มีลำดับของข้อมูลโดยทั่วไปจะไม่มีการนิยาม เมธอด __reversed__ เอาไว้ เมื่อใช้ฟังก์ชัน reversed ก็จะเกิดข้อผิดพลาด

เช่นเซ็ต
s = {78,58,82}
reversed(s) # ได้ TypeError: 'set' object is not reversible

เดิมทีดิกชันนารีเองก็ไม่มีเมธอด __reversed__ ดังนั้นก็จะใช้ reversed ไม่ได้เช่นกัน ในขณะที่ OrderedDict มี __reversed__

แต่ว่าตั้งแต่เวอร์ชัน 3.8 เป็นต้นไป dict ธรรมดาก็สามารถ reversed ได้ ความแตกต่างตรงนี้จึงหายไปแล้ว

ตัวอย่างการใช้ reversed กับ OrderedDict
odadic = OrderedDict([(i**2,i) for i in range(1,7)])
print(odadic) # ได้ OrderedDict([(1, 1), (4, 2), (9, 3), (16, 4), (25, 5), (36, 6)])
print(reversed(odadic)) # ได้ 
print(list(reversed(odadic))) # ได้ [36, 25, 16, 9, 4, 1]
print([(odadic[a],a) for a in reversed(odadic)]) # ได้ [(6, 36), (5, 25), (4, 16), (3, 9), (2, 4), (1, 1)]


อ้างอิง



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

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

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

หมวดหมู่

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

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

目录

从日本来的名言
模块
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
机器学习
-- 神经网络
javascript
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



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

  查看日志

  推荐日志

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