python - I keep getting "ValueError: list.remove(x): x not in list" when looping through nested lists -


i trying make simple version of space invaders, keep running same error

valueerror: list.remove(x): x not in list

trying remove invaders once they've been hit.

here code.

def killenemies(bullets, enemies):     bullet in bullets:         x in enemies:             y in x:                 if bullet.top <= y.bottom , bullet.top >= y.top:                     if bullet.left >= y.left , bullet.right <= y.right:                         x.remove(y)                         bullets.remove(bullet) 

the problem occurs when if statements true, , console says error occurs in last line

here rest of code

import pygame, sys pygame.locals import *   pygame.init()  fps = 30 fpsclock = pygame.time.clock()  displaysurf = pygame.display.set_mode((800, 660), 0, 32) pygame.display.set_caption('space invaders')  white = (255, 255, 255) black = (0, 0, 0) shipx = 50 shipy = 630 displaysurf.fill(black)  timer = fpsclock.tick() time = 0 direction = '' bullets = [] bulletx = shipx + 25 bullety = shipy - 50 enemies = [[], [], [], [], [], [], []] shields = []   def drawenemies(enemies):     y = 0     n in enemies:         x = 0         f in range(7):             enemy = pygame.draw.rect(displaysurf, white, (30 + x, 40 + y, 75, 20))             n.append(enemy)             x += 110         y += 30     return enemies  def killenemies(bullets, enemies):     bullet in bullets:         x in enemies:             y in x:                 if bullet.top <= y.bottom , bullet.top >= y.top:                     if bullet.left >= y.left , bullet.right <= y.right:                     x.remove(y)                     bullets.remove(bullet)   def movebullets(bullets):     bullet in bullets:          bullet.top -= 15     b in bullets:         pygame.draw.rect(displaysurf, white, b)  while true:       if direction == 'left':         shipx -= 8         bulletx -= 8     elif direction == 'right':         shipx += 8         bulletx += 8       event in pygame.event.get():         if event.type == quit:             pygame.quit()             sys.exit()          key = pygame.key.get_pressed()          if key[k_left]:             direction = 'left'         elif key[k_right]:             direction = 'right'         elif key[k_space]:             bullet = pygame.draw.line(displaysurf, white, (bulletx, bullety), (bulletx, bullety - 25), 2)             bullets.append(bullet)          if event.type == keyup:             direction = ''      time += timer             displaysurf.fill(black)     pygame.draw.polygon(displaysurf, white, ((shipx, shipy), (shipx + 25, shipy - 50), (shipx + 50, shipy)), 1)     drawenemies(enemies)     movebullets(bullets)     killenemies(bullets, enemies)     pygame.display.update()     fpsclock.tick(fps) 

you should not try , mutate list while iterating on it. source of issues.

for simple example, try running:

some_list = [1,2,3,4] x in some_list:     some_list.remove(x) print(some_list) # prints [2, 4] 

obviously not expected outcome - perhaps expect entire list empty.

the solution either use list comprehension create new list required elements, or make copy of list iterate over. if go route of creating copy, simple as:

def killenemies(bullets, enemies):     bullet in bullets[:]:         x in enemies:             y in x[:]:                 if bullet.top <= y.bottom , bullet.top >= y.top:                     if bullet.left >= y.left , bullet.right <= y.right:                         x.remove(y)                         bullets.remove(bullet) 

note list[:] creates shallow copy of list, , hence underlying objects in original list , copied list should same.

the other issue having in logic of for loops. each bullet, iterating on multiple enemies, , need break out of 2 inner loops once each bullet 'spent'. written, seems trying remove each bullet multiple times. suggest code refactoring in order here:

def killenemies(bullets, enemies):     bullet in bullets[:]:         iterenemies(bullets, bullet, enemies)  def iterenemies(bullets, bullet, enemies):     x in enemies:         y in x[:]:             if bullet.top <= y.bottom , bullet.top >= y.top:                 if bullet.left >= y.left , bullet.right <= y.right:                     x.remove(y)                     bullets.remove(bullet)                     return 

Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -