2013-01-02 11 views
6

में नहीं x, मैं इस त्रुटि मिलती है यह एक बोल्ट द्वारा मारा जाता है। यदि उसका स्वास्थ्य <= 0 है तो वह एकल विदेशी भी नष्ट किया जाना चाहिए। इसी प्रकार, बोल्ट भी नष्ट हो जाएगा।अजगर 2.7 फेंकता ValueError: list.remove (एक्स):</p> <pre><code>ValueError: list.remove(x): x not in list </code></pre> <p>मैं एक एकल विदेशी जब भी के स्वास्थ्य कम करने के लिए कोशिश कर रहा हूँ: हर बार जब मैं इस कार्यक्रम को चलाने सूची

def manage_collide(bolts, aliens): 
    # Check if a bolt collides with any alien(s) 
    for b in bolts: 
     for a in aliens: 
      if b['rect'].colliderect(a['rect']): 
       for a in aliens: 
        a['health'] -= 1 
        bolts.remove(b) 
        if a['health'] == 0: 
         aliens.remove(a) 
    # Return bolts, aliens dictionaries 
    return bolts, aliens 

ValueError लाइन aliens.remove(a) पर होता है: यहाँ मेरी कोड है। बस स्पष्ट करने के लिए, aliens और bolts दोनों शब्दकोशों की सूचियां हैं।

मैं क्या गलत कर रहा हूं?

+0

किस लाइन पर ValueError? – asheeshr

+0

aliens.remove (ए) –

+0

भविष्य के संदर्भ के लिए, इस कोड के साथ समस्या यह है कि मैंने एलियंस सूची में दो बार लूप किया, जिससे सूची से निकालने का प्रयास करते समय कुछ समस्याएं उत्पन्न होती हैं। दूसरे 'एलियंस के लिए' को हटाने से इस समस्या को रोका जा सकेगा। –

उत्तर

14

आपको उस सूची से आइटम नहीं निकालना चाहिए जिसे आप लूप कर रहे हैं। बजाय एक कॉपी बनाएं: एक सूची से

>>> lst = [1, 2, 3] 
>>> for i in lst: 
...  print i 
...  lst.remove(i) 
... 
1 
3 
>>> lst 
[2] 

आइटम निकाले जा रहे तुम पर पाशन कर रहे हैं दो बार बनाता है:

for a in aliens[:]: 

और

for b in bolts[:]: 

एक सूची में संशोधन करना इस पर पाशन जबकि, पाश को प्रभावित करता है चीजें थोड़ा और जटिल है, जिसके परिणामस्वरूप एक ValueError:

>>> lst = [1, 2, 3] 
>>> for i in lst: 
...  for a in lst: 
...   print i, a, lst 
...   lst.remove(i) 
... 
1 1 [1, 2, 3] 
1 3 [2, 3] 
Traceback (most recent call last): 
  File "<stdin>", line 4, in <module> 
ValueError: list.remove(x): x not in list 

जब सूचियों आप अपने छोरों से प्रत्येक स्तर पर संशोधित कर रहे हैं की एक प्रति बनाते समय, आप समस्या से बचने:

>>> lst = [1, 2, 3] 
>>> for i in lst[:]: 
...  for i in lst[:]: 
...   print i, lst 
...   lst.remove(i) 
... 
1 [1, 2, 3] 
2 [2, 3] 
3 [3] 

आप एक टक्कर है, तो आप केवल एक बार b बोल्ट हटाने की जरूरत, उस लूप में नहीं जहां आप एलियंस को चोट पहुंचाते हैं। बाद में एलियंस को अलग से साफ करें:

def manage_collide(bolts, aliens): 
    for b in bolts[:]: 
     for a in aliens: 
      if b['rect'].colliderect(a['rect']) and a['health'] > 0: 
       bolts.remove(b) 
       for a in aliens: 
        a['health'] -= 1 
    for a in aliens[:]: 
     if a['health'] <= 0: 
      aliens.remove(a) 
    return bolts, aliens 
+1

यह वास्तव में ओपी के प्रश्न का उत्तर नहीं देता है। वास्तव में किसी सूची से आइटम्स को हटाने के दौरान इसे हटाने में कोई समस्या नहीं है; यह सिर्फ इसलिए है कि यह अप्रत्याशित परिणाम उत्पन्न कर सकता है यदि आप नहीं जानते कि यह कैसे काम करता है। – kindall

+0

यह अभी भी एक ही पंक्ति aliens.remove (ए) पर एक ValueError डालता है जब एक प्रतिलिपि सूची में केवल उस पंक्ति को बदलता है। –

+0

@kindall: यह डबल लूप है जो इसे और अधिक मजेदार बनाता है और मूल्य त्रुटि का कारण बन सकता है। –

1

आपके कोड में एक बग है जो इसका कारण बन रहा है। b में प्रत्येक प्रविष्टि के लिए

for b in bolts: 
    for a in aliens: 
    for a in aliens: 
     bolts.remove(b) 

है कि आप पाश करने के लिए खड़ी कर रहा है aliens से अधिक से अधिक बार: अपने कोड, सरल, तरह दिखता है। यदि बी aliens पर पहले लूप पर हटा दिया गया है, तो जब यह दूसरी बार इसे लूप करता है, तो आपको वहां त्रुटि मिल जाएगी।

कुछ चीजें ठीक करने के लिए। सबसे पहले, a के अलावा कुछ का उपयोग करने के aliens से अधिक भीतरी पाश में बदल सकता है इसलिए:

for b in bolts: 
    for a in aliens: 
    for c in aliens: 
     if hit: 
     bolts.remove(b) 

दूसरा, केवल एक बार bolts से b को हटा दें। इसलिए:

for b in bolts: 
    for a in aliens: 
    should_remove = False 
    for c in aliens: 
     if hit: 
     should_remove = True 
    if should_remove: 
     bolts.remove(b) 

इस कोड के साथ अन्य मुद्दे भी हैं, मुझे लगता है, लेकिन यही कारण है कि आपकी मुख्य समस्या है। मार्टिजन की पोस्ट भी मदद कर सकती है।

0

बोल्ट को "स्वास्थ्य" भी दें, 1 से शुरू किया गया।फिर आप सभी क्षति की गणना करने के लिए एक नेस्टेड लूप कर सकते हैं, और "मृत" की सभी चीज़ों को हटाने के लिए दो अलग अनचेस्ट "लूप" कर सकते हैं। इसके अलावा, ऐसा मत करो, क्योंकि आप अभी भी उस सूची को संशोधित नहीं करना चाहते हैं जिस पर आप लूपिंग कर रहे हैं। एक प्रतिलिपि बनाना अभी भी जटिल है। आप वास्तव में क्या करना चाहते हैं सीधे केवल "जीवित" चीजों की एक नई सूची बनाएं, और आप सूची समझ के साथ वर्णनात्मक रूप से ऐसा कर सकते हैं (या जैसा कि यहां दिखाया गया है, filter के साथ)।

# for example 
class Alien: 
    # ... other stuff 
    def damage(self): self.hp -= 1 
    def alive(self): return self.hp > 0 

# similarly for Bolt 

def collide(an_alien, a_bolt): 
    # etc. 

def handle_collisions(aliens, bolts): 
    for a in aliens: 
     for b in bolts: 
      if collide(a, b): 
       a.damage() 
       b.damage() 

    return list(filter(Alien.alive, aliens)), list(filter(Bolt.alive, bolts)) 
संबंधित मुद्दे

 संबंधित मुद्दे