Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Giải pháp lỗi Python TypeError: unhashable type: 'list'

Từ điển Python chỉ chấp nhận kiểu dữ liệu có thể hash (hashable) làm khóa (key). Danh sách (list) không phải kiểu dữ liệu có thể hash. Nếu bạn chỉ định danh sách làm khóa trong từ điển, bạn sẽ gặp lỗi TypeError: unhashable type: 'list'.

Trong hướng dẫn này, chúng ta nói về ý nghĩa lỗi này và tại sao bạn thấy nó trong mã. Chúng ta sẽ đi qua ví dụ để chỉ cách khắc phục.

TypeError: unhashable type: 'list'

Từ điển có hai phần: khóa và giá trị. Khóa là nhãn liên kết với giá trị cụ thể. Để truy xuất giá trị, bạn phải tham chiếu tên khóa của giá trị đó.

Mặc dù giá trị có thể là bất kỳ kiểu dữ liệu nào, từ danh sách đến chuỗi, chỉ đối tượng có thể hash mới chấp nhận được làm khóa. Đối tượng có thể hash là đối tượng có giá trị hash không thay đổi theo thời gian. Ví dụ đối tượng có thể hash là tuple và chuỗi.

Danh sách không có giá trị hash không đổi. Giá trị hash của chúng có thể thay đổi theo thời gian. Điều này có nghĩa là bạn không thể chỉ định danh sách làm khóa từ điển.

Ví dụ minh họa

Xây dựng chương trình tạo danh sách học sinh có điểm trung bình trên 75. Danh sách này chứa bản ghi từ điển mỗi học sinh và điểm. Để tạo từ điển này, chúng ta làm việc từ từ điển chứa danh sách tất cả học sinh và điểm.

Bắt đầu bằng định nghĩa danh sách học sinh và từ điển cho học sinh giỏi:

students = [
    { "name": "Linda", "grades": [84, 82, 65] },
    { "name": "Alex", "grades": [67, 68, 83] },
    { "name": "Holly", "grades": [72, 74, 81] }
]
top_students = {}

Mỗi giá trị trong danh sách "students" là từ điển. Mỗi từ điển chứa hai khóa: name và grades. Chúng ta định nghĩa từ điển "top_students" chứa thông tin học sinh giỏi.

Bây giờ đã định nghĩa từ điển, dùng vòng lặp for lọc học sinh điểm trung bình trên 75 và thêm vào từ điển mới:

for s in students:
    average = sum(s["grades"]) / len(s["grades"])
    if average > 75:
        top_students[s["grades"]] = s["name"]

Trong mỗi vòng lặp, tính trung bình tất cả điểm học sinh đạt. Chia tổng điểm cho số lượng điểm ghi nhận.

Tiếp theo, kiểm tra trung bình có lớn hơn 75 không. Nếu có, tạo mục mới trong top_students với tên học sinh và điểm.

Cuối cùng, in từ điển top_students ra console để xem tất cả học sinh điểm trung bình trên 75:

print(top_students)

Chạy mã:

Traceback (most recent call last):
  File "main.py", line 11, in 
    top_students[s["grades"]] = s["name"]
TypeError: unhashable type: 'list'

Mã không thực thi thành công.

Giải pháp

Mã hoạt động cho đến khi trình thông dịch đến dòng 11. Trên dòng này, mã viết:

top_students[s["grades"]] = s["name"]

Lỗi do chúng ta gán danh sách làm khóa trong từ điển. Khi mã phân tích dòng này ở vòng lặp đầu, mã thử tạo từ điển với khóa và giá trị:

{ [84, 82, 65]: "Linda" }

Đây là từ điển không hợp lệ. Mã thử gán danh sách làm khóa và không hoạt động.

Để khắc phục, dùng tên học sinh làm khóa thay vì danh sách điểm:

top_students[s["name"]] = s["grades"]

Chúng ta gán danh sách điểm làm giá trị thay vì khóa. Tên học sinh là khóa. Chạy mã:

{'Linda': [84, 82, 65], 'Holly': [72, 74, 81]}

Mã tạo thành công từ điển thông tin học sinh giỏi. Học sinh nào điểm trung bình ba bài kiểm tra cuối trên 75 được thêm vào từ điển.

Từ điển phân tích:

  • Khóa: Linda, Holly
  • Giá trị: [84, 82, 65], [72, 74, 81]

Vì giờ gán chuỗi làm tên khóa, mã hoạt động.

Kết luận

Lỗi TypeError: unhashable type: 'list' xảy ra khi bạn gán danh sách làm khóa trong từ điển. Để khắc phục, đảm bảo chỉ gán đối tượng có thể hash, như chuỗi hoặc tuple, làm khóa từ điển.

Bây giờ bạn đã sẵn sàng khắc phục lỗi này như coder chuyên nghiệp!