Python dictionaries รับเฉพาะชนิดข้อมูลที่แฮชได้ (hashable) เท่านั้นในการเป็น key ของ dictionary ในขณะที่ list ไม่ใช่ชนิดข้อมูลที่แฮชได้ หากคุณระบุ list เป็น key ใน dictionary จะพบข้อผิดพลาด "TypeError: unhashable type: 'list'"
ทำความเข้าใจข้อผิดพลาด TypeError: unhashable type: 'list'
Dictionary ประกอบด้วยสองส่วนคือ keys และ values Keys คือป้ายกำกับที่เชื่อมโยงกับค่าเฉพาะ ในการเข้าถึงค่า คุณต้องอ้างอิงชื่อ key ของค่านั้น
แม้ values จะสามารถเป็นชนิดข้อมูลใดก็ได้ ตั้งแต่ list ไปจนถึง string แต่เพียงวัตถุที่แฮชได้เท่านั้นที่ยอมรับเป็น keys วัตถุที่แฮชได้คือวัตถุที่มีค่าแฮชที่ไม่เปลี่ยนแปลงตามเวลา ตัวอย่างเช่น tuples และ strings
List ไม่มีค่าแฮชที่คงที่ ค่าแฮชของ list อาจเปลี่ยนแปลงได้ตลอดเวลา ดังนั้นจึงไม่สามารถระบุ list เป็น key ของ dictionary ได้
ตัวอย่างสถานการณ์
เราจะสร้างโปรแกรมที่กรองนักเรียนที่มีเกรดเฉลี่ยเกิน 75 โปรแกรมจะสร้าง list ของนักเรียนที่ผ่านเกณฑ์ โดยแต่ละรายการเป็น dictionary ที่เก็บข้อมูลนักเรียนและเกรด เราจะเริ่มจาก dictionary ที่มี list ของนักเรียนทั้งหมดในโรงเรียนพร้อมเกรดของพวกเขา
เริ่มต้นด้วยการกำหนด list ของนักเรียนและ dictionary สำหรับนักเรียนดีเด่น:
students = [
{"name": "Linda", "grades": [84, 82, 65]},
{"name": "Alex", "grades": [67, 68, 83]},
{"name": "Holly", "grades": [72, 74, 81]}
]
top_students = {}
แต่ละค่าใน "students" list เป็น dictionary ที่มีสอง keys คือ name และ grades เราได้กำหนด dictionary ชื่อ "top_students" ซึ่งจะเก็บข้อมูลนักเรียนที่มีเกรดเฉลี่ยเกิน 75
for s in students:
average = sum(s["grades"]) / len(s["grades"])
if average > 75:
top_students[s["grades"]] = s["name"]
ในแต่ละรอบของลูป เราคำนวณค่าเฉลี่ยเกรดของนักเรียนแต่ละคนโดยการหารผลรวมเกรดด้วยจำนวนเกรดที่บันทึกไว้
ต่อมา เราตรวจสอบว่าค่าเฉลี่ยมากกว่า 75 หรือไม่ หากใช่ เราจะสร้าง entry ใหม่ใน dictionary top_students โดยใช้ list ของเกรดเป็น key และชื่อนักเรียนเป็น value
สุดท้าย เราพิมพ์ dictionary top_students เพื่อดูรายชื่อนักเรียนที่ผ่านเกณฑ์:
print(top_students)
เมื่อรันโค้ด จะเกิดข้อผิดพลาดดังนี้:
Traceback (most recent call last): File "main.py", line 11, intop_students[s["grades"]] = s["name"] TypeError: unhashable type: 'list'
โค้ดทำงานไม่สำเร็จ
วิธีแก้ไข
โค้ดทำงานปกติจนถึงบรรทัดที่ 11 ซึ่งมีคำสั่ง:
top_students[s["grades"]] = s["name"]
ข้อผิดพลาดเกิดจากการพยายามกำหนด list เป็น key ใน dictionary ในรอบแรกของลูป โค้ดพยายามสร้าง dictionary ที่มี key และ value ดังนี้:
{ [84, 82, 65]: "Linda" }
นี่เป็น dictionary ที่ไม่ถูกต้อง เพราะไม่สามารถใช้ list เป็น key ได้
เพื่อแก้ไข เราควรใช้ชื่อนักเรียนเป็น key แทน list ของเกรด:
top_students[s["name"]] = s["grades"]
เราได้กำหนด list ของเกรดเป็น value แทนที่จะเป็น key ชื่อนักเรียนกลายเป็น key ของ dictionary ลองรันโค้ดใหม่:
{'Linda': [84, 82, 65], 'Holly': [72, 74, 81]}
โค้ดทำงานสำเร็จและสร้าง dictionary ที่มีข้อมูลนักเรียนที่ทำเกรดเฉลี่ยเกิน 75 Dictionary นี้ประกอบด้วย:
- Keys: Linda, Holly
- Values: [84, 82, 65], [72, 74, 81]
เนื่องจากเรากำหนด string เป็น key names โค้ดจึงทำงานได้อย่างถูกต้อง
สรุป
ข้อผิดพลาด "TypeError: unhashable type: 'list'" จะเกิดขึ้นเมื่อคุณพยายามกำหนด list เป็น key ใน dictionary วิธีแก้ไขคือให้แน่ใจว่าคุณกำหนดเฉพาะวัตถุที่แฮชได้ เช่น string หรือ tuple เท่านั้นในการเป็น key ของ dictionary
ตอนนี้คุณพร้อมที่จะแก้ไขข้อผิดพลาดนี้อย่างมืออาชีพแล้ว!