Khắc phục lỗi 'IndexError: list index out of range' trong Python

beginner🐍 Python2026-06-08| Python 3.x (Mọi hệ điều hành: Windows, macOS, Linux)

Error Message

IndexError: list index out of range
#python#danh-sach#indexerror#go-loi#meo-lap-trinh

Giải pháp nhanh (TL;DR)

Lỗi IndexError xảy ra khi bạn cố gắng lấy một phần tử từ danh sách bằng một vị trí (chỉ số - index) không tồn tại. Vì Python bắt đầu đếm từ 0, chỉ số hợp lệ cao nhất luôn nhỏ hơn tổng độ dài của danh sách một đơn vị.

# Cách sửa an toàn nhất: Kiểm tra độ dài trước khi truy cập danh sách
if len(user_ids) > 5:
    print(user_ids[5])
else:
    print("Danh sách quá ngắn!")

Tại sao lỗi này xảy ra?

Hãy tưởng tượng một danh sách giống như một dãy năm ngăn tủ được đánh số từ 0 đến 4. Nếu bạn cố mở ngăn tủ số 5, bạn sẽ thấy nó không tồn tại. Python phản ứng với điều này bằng cách dừng chương trình của bạn và đưa ra lỗi IndexError.

Các sai lầm phổ biến

  • Lỗi lệch một đơn vị (Off-By-One): Bạn có 10 phần tử và cố gắng truy cập chỉ số 10. Hãy nhớ rằng, phần tử thứ 10 thực chất nằm ở chỉ số 9.
  • Danh sách rỗng: Mã của bạn mong đợi có dữ liệu, nhưng danh sách lại là []. Truy cập my_list[0] ở đây sẽ luôn thất bại.
  • Cạm bẫy vòng lặp: Bạn đang xóa các phần tử khỏi danh sách trong khi vẫn đang lặp qua nó. Điều này làm thay đổi kích thước danh sách ngay trong quá trình thực thi.
  • Lạm dụng chỉ số âm: Bạn sử dụng my_list[-5] trên một danh sách chỉ có 3 phần tử.

Cách khắc phục

1. Chuyển sang cách lặp kiểu "Pythonic"

Việc quản lý các biến chỉ số (index) một cách thủ công rất dễ dẫn đến sai sót. Nếu bạn chỉ cần các phần tử, hãy lặp trực tiếp qua danh sách. Cách tiếp cận này sạch sẽ hơn và không thể gây ra lỗi chỉ số.

# Tránh sử dụng bộ đếm thủ công
for i in range(len(prices) + 1): # Phần +1 này sẽ làm hỏng mã của bạn
    print(prices[i])

# Hãy làm như thế này thay thế
for price in prices:
    print(price)

Bạn cũng cần cả số chỉ số? Hãy sử dụng enumerate() để lấy cả số thứ tự và phần tử một cách an toàn:

for index, price in enumerate(prices):
    print(f"Sản phẩm {index} có giá {price}")

2. Sử dụng kiểm tra độ dài phòng vệ

Khi chỉ số của bạn đến từ một nguồn bên ngoài—như dữ liệu nhập của người dùng hoặc cơ sở dữ liệu—hãy xác minh nó trước khi sử dụng. Một câu lệnh if đơn giản có thể ngăn chặn việc sập chương trình hoàn toàn.

def get_user_by_rank(users, rank):
    index = rank - 1 # Chuyển vị trí thứ 1 thành chỉ số 0
    if 0 <= index < len(users):
        return users[index]
    return "Không tìm thấy người dùng"

3. Thử "mẹo" cắt danh sách (Slicing)

Cú pháp cắt (slicing) của Python linh hoạt một cách đáng ngạc nhiên. Trong khi my_list[10] có thể gây crash, my_list[10:11] sẽ chỉ trả về một danh sách rỗng nếu chỉ số đó không tồn tại. Đây là một cách tuyệt vời để lấy dữ liệu mà không cần kiểm tra if liên tục.

colors = ["red", "blue"]

# Cái này sẽ gây crash:
# top_color = colors[2]

# Cái này trả về một danh sách rỗng thay vì gây crash:
result = colors[2:3]
final_color = result[0] if result else "mặc định"

4. Xử lý ngoại lệ (Exception)

Đôi khi việc "xin lỗi sau" sẽ dễ hơn là "xin phép trước". Hãy bao bọc mã của bạn trong một khối try...except để bắt lỗi và cung cấp một giá trị dự phòng.

try:
    latest_post = blog_posts[0]
except IndexError:
    latest_post = "Chưa có bài viết nào!"
    print("Cảnh báo: Danh sách bài viết blog đang trống.")

Gỡ lỗi khi bị Crash

Nếu script của bạn thất bại bên trong một vòng lặp phức tạp, hãy in ra kích thước danh sách và chỉ số ngay trước dòng bị crash. Điều này thường tiết lộ chính xác logic đã sai ở đâu.

print(f"DEBUG: Danh sách có {len(data)} phần tử. Đang cố truy cập chỉ số {i}.")
value = data[i]

Kiểm tra cuối cùng

Trước khi triển khai mã của bạn, hãy kiểm tra nó với ba kịch bản sau:

  • Danh sách rỗng: Mã của bạn có hoạt động được với một danh sách không có phần tử nào không?
  • Một phần tử duy nhất: Nó có xử lý được danh sách chỉ có đúng một phần tử không?
  • Điểm biên: Nếu danh sách có 100 phần tử, mã của bạn có dừng lại chính xác ở chỉ số 99 không?

Related Error Notes