python - 遍历嵌套列表时,我不断收到 "ValueError: list.remove(x): x not in list"

标签 python for-loop pygame

<分区>

我正在尝试制作一个简单版本的太空入侵者,但我一直遇到同样的错误

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

试图在入侵者被击中后将其移除。

这是代码。

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 时才会出现问题,并且控制台显示错误发生在最后一行

这是剩下的代码

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)

最佳答案

你不应该在迭代列表时尝试改变它。这是您问题的根源。

对于一个非常简单的例子,尝试运行:

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

显然不是预期的结果 - 您可能希望整个列表都是空的。

解决方案是要么使用列表理解来创建一个仅包含所需元素的新列表,要么复制该列表以进行迭代。如果您采用创建副本的方式,这很简单:

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)

注意 list[:] 创建列表的浅拷贝,因此原始列表和复制列表中的底层对象应该相同。

您遇到的其他 问题与for 循环的逻辑有关。对于每颗子弹,您都在迭代多个敌人,并且在每颗子弹“用完”后需要跳出两个内部循环。正如所写的那样,您似乎正试图多次删除每颗子弹。我建议在这里进行一些代码重构:

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

关于python - 遍历嵌套列表时,我不断收到 "ValueError: list.remove(x): x not in list",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45687167/

相关文章:

Python pygame事件循环类型错误

python - 加速 Matplotlib

python - bash 脚本可能有语法错误不确定尝试直到循环

Python pandas 替换字符串

python - Boto3 在本地和使用 django 应用程序在弹性 beantalk 上生成不同的链接

java - 将字符串解析为 Java 方法

python - for循环没有执行两次

python - 在 for 循环中后退迭代

python - Sprite 正在碰撞,但球不会向相反方向弹跳

python - Pygame 侧滚轴街机