مشكلة وحل 5: حل خطأ IndexError list index out of range في بايثون

مرحبًا بك في درس جديد من سلسلة مشكلة وحل على موقع بايثون العرب. في هذا المقال سنشرح واحدًا من أشهر أخطاء بايثون التي تواجه المبتدئين عند التعامل مع القوائم Lists، وهو خطأ:

IndexError: list index out of range

هذا الخطأ يظهر عندما تحاول الوصول إلى عنصر داخل قائمة باستخدام رقم فهرس index غير موجود. بمعنى آخر: أنت تطلب من بايثون عنصرًا خارج حدود القائمة.

في هذا الدرس سنفهم معنى الخطأ، ولماذا يحدث، وكيف تحله خطوة بخطوة، وكيف تتجنبه عند استخدام القوائم والحلقات في بايثون.

{getToc} $title={محتوى المقال}

{alertInfo} إذا لم تكن مرتاحًا مع القوائم بعد، أنصحك أولًا بقراءة درس شرح القوائم Lists في Python للمبتدئين.

قصة المشكلة

لنفترض أنك أنشأت قائمة تحتوي على ثلاثة أسماء:

names = ["Ahmed", "Sara", "Omar"]

print(names[3])

عند تشغيل الكود سيظهر الخطأ:

IndexError: list index out of range

السبب أن القائمة تحتوي على ثلاثة عناصر فقط، لكن الفهارس في بايثون تبدأ من الصفر. لذلك العناصر الموجودة هي:

names[0]  # Ahmed
names[1]  # Sara
names[2]  # Omar

أما names[3] فهو عنصر رابع غير موجود، لذلك يظهر خطأ IndexError.

ما معنى IndexError list index out of range؟

رسالة IndexError: list index out of range تعني أن رقم الفهرس الذي استخدمته خارج نطاق القائمة.

كلمة index تعني رقم مكان العنصر داخل القائمة، وكلمة out of range تعني خارج الحدود المتاحة.

مثال بسيط:

fruits = ["Apple", "Banana", "Orange"]

هذه القائمة طولها 3 عناصر، لكن الفهارس المتاحة هي:

العنصر الفهرس index
Apple 0
Banana 1
Orange 2

إذن الفهرس 3 غير موجود، رغم أن عدد العناصر هو 3.

{alertWarning} قاعدة مهمة جدًا: إذا كان طول القائمة 3، فإن آخر index هو 2، لأن العد في بايثون يبدأ من 0.

سبب الخطأ ببساطة

سبب الخطأ هو محاولة الوصول إلى عنصر غير موجود داخل القائمة.

إذا كانت القائمة تحتوي على 3 عناصر، فالحدود الصحيحة للفهرسة هي:

0, 1, 2

لكن هذا غير صحيح:

names[3]

لأن الفهرس 3 خارج حدود القائمة.

الحل الأول: استخدم index صحيح

أبسط حل هو استخدام رقم فهرس موجود داخل القائمة.

الكود الخاطئ:

names = ["Ahmed", "Sara", "Omar"]

print(names[3])

الكود الصحيح:

names = ["Ahmed", "Sara", "Omar"]

print(names[2])

الناتج:

Omar

استخدمنا names[2] لأن Omar هو العنصر الثالث، ورقمه في بايثون هو 2.

الحل الثاني: استخدم len لمعرفة طول القائمة

الدالة len() تساعدك على معرفة عدد عناصر القائمة.

names = ["Ahmed", "Sara", "Omar"]

print(len(names))

الناتج:

3

لكن انتبه: len(names) يعطينا عدد العناصر، وليس آخر فهرس.

للوصول إلى آخر عنصر باستخدام الطول، نكتب:

last_index = len(names) - 1

print(names[last_index])

لأن آخر فهرس دائمًا يساوي طول القائمة ناقص 1.

الحل الثالث: استخدم -1 للوصول إلى آخر عنصر

إذا كنت تريد الوصول إلى آخر عنصر في القائمة، فلا تحتاج دائمًا إلى حساب الطول. يمكنك استخدام الفهرس السالب -1.

names = ["Ahmed", "Sara", "Omar"]

print(names[-1])

الناتج:

Omar

في بايثون:

  • -1 يعني آخر عنصر.
  • -2 يعني العنصر قبل الأخير.
  • -3 يعني العنصر الثالث من النهاية.

الحل الرابع: تحقق من رقم index قبل استخدامه

إذا كان رقم الفهرس يأتي من المستخدم أو من متغير، فمن الأفضل التحقق منه قبل الوصول إلى القائمة.

names = ["Ahmed", "Sara", "Omar"]

index = 3

if 0 <= index < len(names):
    print(names[index])
else:
    print("هذا الرقم خارج حدود القائمة")

الناتج:

هذا الرقم خارج حدود القائمة

هذا الشرط يتأكد أن الفهرس أكبر أو يساوي صفر، وأصغر من طول القائمة.

{alertSuccess} إذا كان index يأتي من المستخدم، لا تستخدمه مباشرة. تحقق منه أولًا حتى لا يتوقف البرنامج.

خطأ شائع داخل الحلقات

أحيانًا يظهر خطأ list index out of range داخل حلقة for، خصوصًا عند استخدام range() برقم أكبر من طول القائمة.

مثال خاطئ:

numbers = [10, 20, 30]

for i in range(4):
    print(numbers[i])

القائمة تحتوي على 3 عناصر فقط، لكن الحلقة تحاول الوصول إلى:

0, 1, 2, 3

والفهرس 3 غير موجود، لذلك يظهر الخطأ.

الحل الصحيح:

numbers = [10, 20, 30]

for i in range(len(numbers)):
    print(numbers[i])

هنا استخدمنا len(numbers) حتى تكون الحلقة بنفس طول القائمة.

الأفضل: مر على عناصر القائمة مباشرة

في كثير من الحالات لا تحتاج إلى استخدام الفهرس أصلًا. يمكنك المرور على العناصر مباشرة.

بدل هذا:

numbers = [10, 20, 30]

for i in range(len(numbers)):
    print(numbers[i])

اكتب هذا:

numbers = [10, 20, 30]

for number in numbers:
    print(number)

هذه الطريقة أوضح وأسهل وأقل عرضة للأخطاء، خصوصًا للمبتدئين.

استخدام enumerate إذا كنت تحتاج index والقيمة معًا

إذا كنت تحتاج إلى رقم العنصر وقيمته معًا، استخدم الدالة enumerate() بدل كتابة الفهارس يدويًا.

names = ["Ahmed", "Sara", "Omar"]

for index, name in enumerate(names):
    print(index, name)

الناتج:

0 Ahmed
1 Sara
2 Omar

وإذا أردت أن يبدأ الترقيم من 1 في العرض فقط:

names = ["Ahmed", "Sara", "Omar"]

for index, name in enumerate(names, start=1):
    print(index, name)
{alertInfo} استخدم enumerate عندما تحتاج إلى رقم العنصر والقيمة معًا. أما إذا كنت تحتاج القيمة فقط، فاستخدم for item in list.

خطأ شائع مع القائمة الفارغة

قد يظهر نفس الخطأ إذا حاولت الوصول إلى عنصر داخل قائمة فارغة.

items = []

print(items[0])

القائمة هنا لا تحتوي على أي عنصر، لذلك لا يوجد شيء اسمه items[0].

الحل:

items = []

if items:
    print(items[0])
else:
    print("القائمة فارغة")

في بايثون، القائمة الفارغة تعتبر False داخل الشرط، لذلك يمكن التحقق منها بهذه الطريقة.

استخدام try except للتعامل مع الخطأ

يمكنك استخدام try except للتعامل مع الخطأ بدون إيقاف البرنامج، لكن الأفضل أن تستخدمها عندما يكون احتمال الخطأ واردًا فعلًا، وليس كبديل عن فهم السبب.

names = ["Ahmed", "Sara", "Omar"]

try:
    print(names[5])
except IndexError:
    print("العنصر المطلوب غير موجود في القائمة")

هذا الكود لن يتوقف بسبب الخطأ، بل سيطبع رسالة مفهومة للمستخدم.

{alertWarning} لا تجعل try except تخفي أخطاءك دائمًا. افهم السبب أولًا، ثم استخدمها عندما تحتاج إلى جعل البرنامج أكثر أمانًا.

مثال عملي: طباعة أول وآخر عنصر بأمان

هذا مثال بسيط يوضح كيف نطبع أول وآخر عنصر من القائمة بدون ظهور خطأ إذا كانت القائمة فارغة.

names = ["Ahmed", "Sara", "Omar"]

if names:
    print("أول اسم:", names[0])
    print("آخر اسم:", names[-1])
else:
    print("القائمة فارغة")

هذا الأسلوب آمن وواضح، لأنه لا يحاول الوصول إلى عناصر القائمة إلا إذا كانت تحتوي على عناصر بالفعل.

جدول سريع لأسباب الخطأ وحلوله

سبب الخطأ مثال المشكلة الحل
استخدام index غير موجود names[3] مع قائمة طولها 3 استخدم آخر فهرس صحيح: names[2]
نسيان أن العد يبدأ من صفر تظن أن العنصر الأول رقمه 1 تذكر أن أول عنصر رقمه 0
حلقة أكبر من طول القائمة range(4) مع قائمة طولها 3 استخدم range(len(list)) أو مر على العناصر مباشرة
القائمة فارغة items[0] والقائمة لا تحتوي عناصر تحقق من القائمة باستخدام if items:
تحتاج index والقيمة كتابة الفهارس يدويًا استخدم enumerate()

أفضل طريقة لتجنب الخطأ

لتجنب خطأ list index out of range، اتبع هذه النصائح:

  • تذكر أن الفهرسة في بايثون تبدأ من الصفر.
  • استخدم len() لمعرفة طول القائمة.
  • لا تستخدم أرقامًا عشوائية للوصول إلى عناصر القائمة.
  • استخدم for item in list إذا كنت لا تحتاج إلى index.
  • استخدم enumerate() إذا كنت تحتاج إلى index والقيمة معًا.
  • تحقق من أن القائمة ليست فارغة قبل الوصول إلى عناصرها.
  • تحقق من قيمة index إذا كانت قادمة من المستخدم.

روابط مفيدة

الخلاصة

خطأ IndexError: list index out of range يظهر عندما تحاول الوصول إلى عنصر غير موجود داخل القائمة. السبب الأكثر شيوعًا هو نسيان أن العد في بايثون يبدأ من الصفر، أو استخدام رقم index أكبر من آخر فهرس متاح.

لحل المشكلة، تأكد من طول القائمة باستخدام len()، واستخدم فهرسًا صحيحًا، أو مر على عناصر القائمة مباشرة باستخدام for. وإذا كنت تحتاج إلى رقم العنصر وقيمته، استخدم enumerate().

{alertSuccess} الخلاصة السريعة: إذا كانت القائمة تحتوي على 3 عناصر، فالفهارس الصحيحة هي 0 و 1 و 2 فقط. لا يوجد index رقم 3.

إرسال تعليق

أحدث أقدم