I keep getting “ValueError: list.remove(x): x not in list” when looping through nested lists
本问题已经有最佳答案,请猛点这里访问。
我在试着做一个简单的太空入侵者版本,我总是遇到同样的错误。
ValueError: list.remove(x): x not in list
号
试图在入侵者被击中后将其清除。
这是密码。
1 2 3 4 5 6 7 8 | def killEnemies(bullets, enemies): for bullet in bullets: for x in enemies: for y in x: if bullet.top <= y.bottom and bullet.top >= y.top: if bullet.left >= y.left and bullet.right <= y.right: x.remove(y) bullets.remove(bullet) |
只有当if语句为true时才会出现问题,并且控制台说错误发生在最后一行
这是剩下的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | import pygame, sys from 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 for n in enemies: x = 0 for 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): for bullet in bullets: for x in enemies: for y in x: if bullet.top <= y.bottom and bullet.top >= y.top: if bullet.left >= y.left and bullet.right <= y.right: x.remove(y) bullets.remove(bullet) def moveBullets(bullets): for bullet in bullets: bullet.top -= 15 for 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 for 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) |
号
在迭代列表时,不应该尝试改变它。这是你问题的根源。
对于一个非常简单的示例,请尝试运行:
1 2 3 4 | some_list = [1,2,3,4] for x in some_list: some_list.remove(x) print(some_list) # Prints [2, 4] |
显然不是预期的结果——您可能期望整个列表是空的。
解决方案是使用一个列表理解来创建一个只包含您所需元素的新列表,或者复制一个列表进行迭代。如果您按照创建副本的路线进行操作,这很简单:
1 2 3 4 5 6 7 8 | def killEnemies(bullets, enemies): for bullet in bullets[:]: for x in enemies: for y in x[:]: if bullet.top <= y.bottom and bullet.top >= y.top: if bullet.left >= y.left and bullet.right <= y.right: x.remove(y) bullets.remove(bullet) |
号
注意,
另一个问题是
1 2 3 4 5 6 7 8 9 10 11 12 | def killEnemies(bullets, enemies): for bullet in bullets[:]: iterEnemies(bullets, bullet, enemies) def iterEnemies(bullets, bullet, enemies): for x in enemies: for y in x[:]: if bullet.top <= y.bottom and bullet.top >= y.top: if bullet.left >= y.left and bullet.right <= y.right: x.remove(y) bullets.remove(bullet) return |