ترجمه - python: فهرس القائمة خارج نطاق الخطأ




tuple in python (5)

لقد كتبت برنامج بايثون بسيط

l=[1,2,3,0,0,1]
for i in range(0,len(l)):
       if l[i]==0:
           l.pop(i)

هذا يعطيني 'قائمة فهرس' الخطأ خارج النطاق '' على الخط if l[i]==0:

بعد التصحيح يمكنني معرفة أن يتم الحصول على زيادة ويتم الحصول على قائمة تقليل.
ومع ذلك ، لدي شرط إنهاء حلقة i < len(l) . إذن لماذا أواجه هذا الخطأ؟

https://code.i-harness.com


أنا أستخدم python 3.3.5. الحل أعلاه من استخدام أثناء حلقة لم يعمل بالنسبة لي. حتى لو وضعت print (i) بعد len(l) أعطتني خطأ. ركضت نفس الرمز في سطر الأوامر (shell) [النافذة التي تنبثق عندما نقوم بتشغيل وظيفة] يتم تشغيلها بدون أخطاء. ما فعلته تم حسابه len (l) خارج الدالة في البرنامج الرئيسي ومرر الطول كمعلمة. انها عملت. بايثون غريبة في بعض الأحيان.


أنت تخفّض طول قائمتك أثناء تكرارها ، حتى إذا اقتربت من نهاية مؤشراتك في بيان النطاق ، فإن بعض تلك المؤشرات لم تعد صالحة.

يبدو أن ما تريد فعله هو:

l = [x for x in l if x != 0]

التي ستعيد نسخة من l بدون أي عنصر من العناصر التي كانت صفراً (تلك العملية تسمى فهم القائمة ، بالمناسبة). يمكنك اختصار هذا الجزء الأخير إلى if x ، حيث يتم تقييم الأرقام غير الصفرية إلى True .

لا يوجد شيء مثل حالة إنهاء الحلقة loop i < len(l) ، بالطريقة التي كتبت بها الشفرة ، لأن len(l) تم حسابه مسبقًا قبل الحلقة ، ولم تتم إعادة تقييمه في كل تكرار. يمكنك كتابة ذلك بطريقة ، ومع ذلك:

i = 0
while i < len(l):
   if l[i] == 0:
       l.pop(i)
   else:
       i += 1

سيقودك فهم القائمة إلى حل.

لكن الطريقة الصحيحة لنسخ كائن في python تستخدم نسخة وحدة python - العمليات الضحلة وعميقة النسخ.

l=[1,2,3,0,0,1]
for i in range(0,len(l)):
   if l[i]==0:
       l.pop(i)

إذا بدلاً من هذا ،

import copy
l=[1,2,3,0,0,1]
duplicate_l = copy.copy(l)
for i in range(0,len(l)):
   if l[i]==0:
       m.remove(i)
l = m

ثم ، قد يعمل الرمز الخاص بك. ولكن من أجل التحسين ، يعد فهم القوالب حلاً جيدًا.


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

على سبيل المثال ، بعد التشغيل الأول ، عند إزالة (i) باستخدام l.pop(i) ، حدث ذلك بنجاح ولكن في الحلقة التالية تغير طول القائمة بحيث تم تغيير جميع أرقام الفهرس. إلى نقطة معينة يحاول الحلقة تشغيل قائمة مختصرة بإلقاء الخطأ.

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

لأولئك منكم الذين قد وصلوا إلى نفس المشكلة.


يتم تقييم التعبير len(l) مرة واحدة فقط ، في اللحظة التي يتم فيها تقييم range() المضمّن. كائن المدى الذي تم إنشاؤه في ذلك الوقت لا يتغير ؛ لا يمكن أن تعرف أي شيء عن الكائن l .

PS l هو اسم رديء لقيمة! يبدو مثل الرقم 1 ، أو الحرف الأول.





list