في هذا الدرس من سلسلة مشكلة وحل على موقع عرب بايثون، سنتحدث عن واحد من أشهر الأخطاء التي تظهر للمبتدئين عند التعامل مع القوائم في بايثون، وهو خطأ:
IndexError: list index out of range
هذا الخطأ قد يبدو مزعجًا في البداية، لكنه في الحقيقة من أسهل أخطاء بايثون فهمًا وحلًا. معناه ببساطة أنك تحاول الوصول إلى عنصر غير موجود داخل القائمة.
{getToc} $title={محتوى المقال}
في هذا المقال سنشرح سبب ظهور الخطأ، وكيف تحله خطوة بخطوة، وكيف تتجنبه عند كتابة برامجك.
إذا لم تكن مرتاحًا مع القوائم بعد، أنصحك أولًا بقراءة: أساسيات بايثون 8: شرح القوائم Lists في Python للمبتدئين.
قصة المشكلة
وصلتنا مشكلة من أحد متابعي عرب بايثون يقول فيها:
"كنت أتعلم القوائم في بايثون، وأنشأت قائمة أسماء، ثم حاولت طباعة عنصر معين، لكن ظهر لي خطأ مكتوب فيه:
IndexError: list index out of range.
لم أفهم لماذا ظهر الخطأ مع أن القائمة موجودة."
الكود الذي كان يحاول تشغيله كان بهذا الشكل:
names = ["Ahmed", "Sara", "Omar"]
print(names[3])
وعند تشغيل الكود ظهر الخطأ:
IndexError: list index out of range
ما معنى IndexError في بايثون؟
كلمة IndexError تعني أن هناك مشكلة في رقم الفهرس index الذي تستخدمه للوصول إلى عنصر داخل قائمة.
في بايثون، عناصر القائمة تبدأ من الرقم 0 وليس من الرقم 1.
مثال:
names = ["Ahmed", "Sara", "Omar"]
الفهارس داخل هذه القائمة تكون كالتالي:
names[0] # Ahmed
names[1] # Sara
names[2] # Omar
يعني آخر عنصر في القائمة رقمه 2، وليس 3.
لذلك عندما نكتب:
print(names[3])
فنحن نطلب من بايثون عنصرًا رابعًا غير موجود، لذلك يظهر الخطأ.
سبب الخطأ ببساطة
سبب خطأ list index out of range هو أنك تحاول استخدام رقم index خارج حدود القائمة.
إذا كانت القائمة تحتوي على 3 عناصر، فالفهارس المتاحة هي:
0, 1, 2
لكن الفهرس 3 غير موجود.
الحل الأول: استخدم index صحيح
لحل المشكلة في المثال السابق، نستخدم رقمًا موجودًا داخل حدود القائمة.
الكود الخاطئ:
names = ["Ahmed", "Sara", "Omar"]
print(names[3])
الكود الصحيح:
names = ["Ahmed", "Sara", "Omar"]
print(names[2])
الناتج:
Omar
الحل الثاني: استخدم len لمعرفة طول القائمة
الدالة len() تساعدك على معرفة عدد عناصر القائمة.
names = ["Ahmed", "Sara", "Omar"]
print(len(names))
الناتج:
3
لكن تذكر: إذا كان طول القائمة 3، فإن آخر index هو 2.
لأن العد يبدأ من الصفر.
كيف أصل إلى آخر عنصر بطريقة آمنة؟
بدل أن تحاول تخمين رقم آخر عنصر، يمكنك استخدام الفهرس السالب -1.
names = ["Ahmed", "Sara", "Omar"]
print(names[-1])
الناتج:
Omar
في بايثون، -1 يعني آخر عنصر، و -2 يعني العنصر قبل الأخير.
الحل الثالث: تحقق من وجود العنصر قبل الوصول إليه
إذا كنت تستخدم رقم index متغيرًا، فمن الأفضل أن تتأكد أنه داخل حدود القائمة قبل استخدامه.
names = ["Ahmed", "Sara", "Omar"]
index = 3
if index < len(names):
print(names[index])
else:
print("هذا الرقم خارج حدود القائمة")
الناتج:
هذا الرقم خارج حدود القائمة
بهذه الطريقة لن يتوقف البرنامج بسبب الخطأ.
خطأ شائع داخل الحلقات
أحيانًا يظهر هذا الخطأ أثناء استخدام حلقة 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) حتى تكون الحلقة بنفس طول القائمة.
الأفضل: مر على عناصر القائمة مباشرة
في كثير من الحالات، لا تحتاج إلى استخدام index أصلًا.
بدل هذا:
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
هذه الطريقة أفضل من كتابة أرقام الفهارس يدويًا.
خطأ شائع مع القائمة الفارغة
قد يظهر الخطأ أيضًا إذا حاولت الوصول إلى عنصر داخل قائمة فارغة.
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("العنصر المطلوب غير موجود في القائمة")
لكن لا تستخدم try except كحل عشوائي دائمًا. الأفضل أن تفهم سبب الخطأ وتمنعه من البداية.
أفضل طريقة لتجنب الخطأ
لتجنب خطأ list index out of range، اتبع هذه النصائح:
- تذكر أن الفهرسة في بايثون تبدأ من الصفر.
- استخدم
len()لمعرفة طول القائمة. - لا تستخدم أرقامًا عشوائية للوصول إلى العناصر.
- استخدم
for item in listإذا لم تكن تحتاج إلى index. - استخدم
enumerate()إذا كنت تحتاج إلى index والقيمة. - تحقق أن القائمة ليست فارغة قبل الوصول إلى عناصرها.
مثال عملي: طباعة أول وآخر عنصر بأمان
هذا مثال بسيط يوضح كيف نطبع أول وآخر عنصر من القائمة بدون ظهور خطأ إذا كانت القائمة فارغة.
names = ["Ahmed", "Sara", "Omar"]
if names:
print("أول اسم:", names[0])
print("آخر اسم:", names[-1])
else:
print("القائمة فارغة")
هذا الأسلوب آمن وواضح للمبتدئين.
روابط مفيدة
لفهم القوائم بشكل أعمق، اقرأ: شرح القوائم Lists في Python للمبتدئين.
ولرؤية مثال عملي على القوائم، اقرأ: بايثون بالمثال: حذف التكرار من قائمة في Python.
ويمكنك الرجوع إلى توثيق بايثون الرسمي حول القوائم وهياكل البيانات: Python Data Structures Documentation.
مقالات مقترحة من عرب بايثون
- فن قراءة رسائل الخطأ في بايثون للمبتدئين
- ما الفرق بين List و Tuple و Set و Dictionary في بايثون؟
- شرح Sets في Python للمبتدئين
خلاصة الحل
خطأ IndexError: list index out of range يظهر عندما تحاول الوصول إلى عنصر غير موجود داخل القائمة.
لحل المشكلة، تذكر هذه القواعد:
- أول عنصر في القائمة رقمه
0. - إذا كانت القائمة تحتوي على 3 عناصر، فإن آخر index هو
2. - استخدم
len()لمعرفة طول القائمة. - استخدم
-1للوصول إلى آخر عنصر. - استخدم
enumerate()عند الحاجة إلى index والقيمة. - تحقق من أن القائمة ليست فارغة قبل الوصول إلى عناصرها.
كلما فهمت طريقة عمل الفهارس في القوائم، ستصبح أخطاء IndexError سهلة جدًا بالنسبة لك.
