رفع خطاهای پایتون

خطای IndexError: list index out of range در پایتون؛ علت و رفع

خطای IndexError: list index out of range در پایتون؛ علت و رفع

🗓 آخرین به‌روزرسانی:

پیام IndexError: list index out of range یعنی خواسته‌اید عضوی از لیست را بخوانید که وجود ندارد. مثلاً لیستی سه‌عضوی دارید و سراغ عضو چهارم رفته‌اید. چون ایندکس‌گذاری در پایتون از صفر شروع می‌شود، این خطا به‌خصوص برای تازه‌کارها بسیار پیش می‌آید.

معنی خطای IndexError در پایتون

در لیستی با n عضو، ایندکس‌های معتبر از 0 تا n-1 هستند (و ایندکس‌های منفی از -1 تا -n). هر ایندکسی خارج از این بازه باعث IndexError می‌شود. همین خطا با پیام string index out of range برای رشته‌ها و tuple index out of range برای تاپل‌ها هم رخ می‌دهد.

علت‌های رایج این خطا

  • فراموش کردن اینکه ایندکس از صفر شروع می‌شود و آخرین عضو ایندکس len(lst) - 1 دارد.
  • حلقه‌ای مثل range(len(lst) + 1) که یک قدم جلوتر می‌رود.
  • دسترسی به عضو اول یک لیست خالی.
  • تغییر طول لیست (حذف عضو) در حین پیمایش آن.
  • فرض اینکه split() همیشه تعداد مشخصی بخش برمی‌گرداند.

کد غلط و کد درست (با خروجی واقعی)

همه نمونه‌کدهای زیر با پایتون 3.13.5 اجرا شده‌اند و خروجی‌ها همان چیزی است که پایتون واقعاً نمایش می‌دهد.

مثال 1: ایندکس برابر با طول لیست

❌ کد غلط:

fruits = ["apple", "banana", "orange"]
print(fruits[3])

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 2, in <module>
    print(fruits[3])
          ~~~~~~^^^
IndexError: list index out of range

✅ کد درست:

fruits = ["apple", "banana", "orange"]
print(fruits[2])   # last item
print(fruits[-1])  # safer way

خروجی:

orange
orange

مثال 2: حلقه با یک قدم اضافه

❌ کد غلط:

nums = [10, 20, 30]
for i in range(len(nums) + 1):
    print(nums[i])

خروجی:

10
20
30
Traceback (most recent call last):
  File "/home/user/project/main.py", line 3, in <module>
    print(nums[i])
          ~~~~^^^
IndexError: list index out of range

✅ کد درست:

nums = [10, 20, 30]
for n in nums:
    print(n)

خروجی:

10
20
30

مثال 3: لیست خالی

❌ کد غلط:

items = []
print(items[0])

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 2, in <module>
    print(items[0])
          ~~~~~^^^
IndexError: list index out of range

✅ کد درست:

items = []
if items:
    print(items[0])
else:
    print("The list is empty")

خروجی:

The list is empty

راه‌حل قدم‌به‌قدم

  1. طول لیست را درست قبل از خط خطا با print(len(lst)) چاپ کنید.
  2. ایندکس استفاده‌شده را هم چاپ کنید و مطمئن شوید بین 0 و len(lst)-1 است.
  3. به جای پیمایش با ایندکس، مستقیماً روی اعضا حلقه بزنید یا از enumerate() استفاده کنید.
  4. قبل از دسترسی به lst[0] بررسی کنید لیست خالی نباشد.
  5. برای حذف عضو در حین پیمایش، روی کپی لیست حلقه بزنید یا لیست جدیدی با List Comprehension بسازید.

خواندن پیام IndexError و عیب‌یابی

IndexError با پیام list index out of range یعنی ایندکسی خواسته‌اید که در لیست، رشته یا تاپل وجود ندارد. در پایتون ایندکس از صفر شروع می‌شود، پس لیستی با سه عضو ایندکس‌های 0، 1 و 2 دارد و items[3] خطا می‌دهد. ایندکس منفی هم مجاز است ولی نباید از منفی طول لیست کمتر باشد.

برای پیدا کردن علت، درست قبل از خط خطا طول لیست و مقدار ایندکس را چاپ کنید. رایج‌ترین موارد عبارت‌اند از حلقه با range(len(items) + 1)، دسترسی به items[0] روی لیست خالی و تغییر طول لیست داخل حلقه. توجه کنید که برش (slice) هیچ‌وقت IndexError نمی‌دهد و فقط لیست کوتاه‌تر برمی‌گرداند.

ایندکس، برش و دسترسی امن

items = ["a", "b", "c"]
print("Length:", len(items), "Last:", items[-1])

try:
    items[3]
except IndexError as error:
    print(type(error).__name__, "-", error)

print("Slice:", items[2:10])
first = items[0] if items else None
print("First:", first)

for index, value in enumerate(items):
    print(index, value)

خروجی (اجراشده با Python 3.13):

Length: 3 Last: c
IndexError - list index out of range
Slice: ['c']
First: a
0 a
1 b
2 c

قدم‌به‌قدم رفع IndexError

این خطا همیشه با مقایسه دو عدد حل می‌شود: ایندکس و طول.

  1. هر دو عدد را چاپ کنید: print(i, len(items)) را درست قبل از خط خطا بگذارید.
  2. خطای یکی‌اضافه را بررسی کنید: range(len(items) + 1) یا شرط i <= len(items) رایج‌ترین علت است.
  3. لیست خالی را در نظر بگیرید: اگر len صفر است، دلیل خالی بودن داده (فیلتر، فایل یا API) را پیدا کنید.
  4. تغییر لیست در حلقه را چک کنید: حذف عضو هنگام پیمایش طول را کم می‌کند و ایندکس‌های بعدی از محدوده خارج می‌شوند.
  5. الگوی امن‌تر به کار ببرید: از for item in items، enumerate، items[-1] یا برش استفاده کنید.

در داده‌هایی که از فایل یا وب می‌خوانید، تعداد اعضا ممکن است از ردیفی به ردیف دیگر فرق کند؛ مثلاً یک خط CSV ستون کمتری دارد یا خط آخر فایل خالی است. قبل از ایندکس‌گذاری روی نتیجه split، طول آن را بررسی کنید و خط‌های ناقص را با پیام مناسب کنار بگذارید. این کار جلوی توقف ناگهانی برنامه در میانه پردازش هزاران خط را می‌گیرد.

چک‌لیست پیشگیری

  • به جای range(len(items)) مستقیماً روی لیست یا با enumerate حلقه بزنید.
  • قبل از items[0] بررسی کنید لیست خالی نباشد.
  • برای آخرین عضو از items[-1] استفاده کنید نه items[len(items)].
  • هنگام حذف عضو، روی کپی لیست حلقه بزنید یا با list comprehension لیست جدید بسازید.
  • در خواندن خط‌های CSV یا split، تعداد بخش‌ها را قبل از ایندکس‌گذاری بررسی کنید.

📌 همچنین بخوانید: خطای unexpected EOF while parsing در پایتون، خطای ‘int’ object is not subscriptable در پایتون و خطای ImportError

سؤالات متداول

چرا ایندکس لیست در پایتون از صفر شروع می‌شود؟

ایندکس در واقع فاصله از ابتدای لیست است؛ عضو اول فاصله صفر دارد. این قرارداد در بیشتر زبان‌های برنامه‌نویسی رایج است.

آیا برش (Slicing) هم IndexError می‌دهد؟

خیر. برش مثل lst[1:100] حتی اگر از طول لیست بیشتر باشد خطا نمی‌دهد و فقط اعضای موجود را برمی‌گرداند.

چطور ایندکس و مقدار را هم‌زمان در حلقه داشته باشم؟

از for i, item in enumerate(lst): استفاده کنید؛ این روش هم خواناتر است و هم احتمال خطای ایندکس را کم می‌کند.

string index out of range چه فرقی دارد؟

همان خطاست ولی روی رشته؛ یعنی شماره کاراکتری خواسته‌اید که از طول رشته بیشتر است.

چرا slice خطا نمی‌دهد ولی ایندکس می‌دهد؟

طراحی پایتون این است که برش، بخش موجود را برگرداند و خارج از محدوده را نادیده بگیرد؛ ایندکس اما باید دقیقاً یک عضو را نشان دهد.

IndexError در pandas چطور رخ می‌دهد؟

معمولاً با iloc و شماره ردیفی بیشتر از تعداد ردیف‌ها؛ len(df) را بررسی کنید یا از head و tail استفاده کنید.

آموزش‌های مرتبط

آموزش‌های تازه، کد آماده و رفع خطاهر هفته در کانال Dev Source؛ رایگان.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *