【发布时间】:2023-02-23 01:39:20
【问题描述】:
当子弹与墙壁碰撞时,我正试图从列表中删除它们。该程序正确地移除了一些子弹,但最终在子弹击中墙壁时抛出“ValueError: list.remove(x): x not in list”错误。
该错误发生在 Bullet 类的 delete() 方法中,并且仅在敌人发射子弹时发生。从玩家发射的子弹不会产生任何错误。
class Bullet(Turtle):
def __init__(self, player, list):
super().__init__()
self.speed(0)
self.ht()
self.pu()
self.color("white")
self.goto(player.xcor(), player.ycor())
self.setheading(player.heading())
self.forward(40)
self.list = list
self.st()
# move the bullet
def move(self):
self.forward(15)
if self.ycor()>300 or self.ycor()< -300:
self.delete()
# delete the bullet
def delete(self):
self.ht()
self.list.remove(self)
def update(counter):
if len(enemies)>0 and player.alive:
# move each of the enemies
for alien in enemies:
alien.move()
if alien.ycor() < - 200 or alien.distance(player)<30:
player.delete()
# randomly select an enemy to fire a bullet.
if counter % 10 == 0:
index = random.randint(0,len(enemies)-1)
bullets.append(Bullet(enemies[index],bullets))
# move each bullet fired by the enemies
for bullet in bullets[:]:
bullet.move()
# check for collision with player
if bullet.distance(player)<20:
player.delete()
# check for collision with a wall
for wall in walls[:]:
if bullet.distance(wall)<15:
wall.strike()
bullet.delete()
# move bullets fired by the player
for bullet in player.rounds:
bullet.move()
# check for collision with an enemy
for alien in enemies:
if bullet.distance(alien)<20:
bullet.delete()
alien.delete(enemies)
counter += 1
screen.ontimer(lambda:update(counter),30)
我遇到了这个问题,因为该程序使用 for 循环使用 bullet in bullets 的语法迭代项目符号列表。尽管项目符号可能存在于列表中,但当程序尝试从同一个列表中删除它时,它无法删除。
我试图通过复制列表来解决问题,但这并没有帮助我修复错误。
【问题讨论】:
-
当您想在迭代列表的同时从列表中删除项目时,常见的解决方案是迭代列表的副本,但您需要从原始列表中删除项目,而不是从副本中删除。另外,为什么 Bullet 类包含一个列表?
-
除了@jarmod 所说的
listisba 是任何东西的糟糕名称,它会很快产生很难找到错误,恕我直言。没有完整的上下文,但项目符号类不应将项目符号列表作为属性。 -
请问您可以使用minimal, reproducible amount,而不是粘贴所有代码吗?这将使调试变得容易得多。
-
谢谢大家的建议:
-
使用“列表”作为名称可能会造成混淆。在此上下文中,“列表”是指项目符号的集合。该程序将维护两个子弹列表:一个用于敌人发射的子弹,另一个用于玩家发射的子弹。项目符号对象存储它所属的列表似乎是循环的,但我想不出更好的方法让项目符号识别它应该从哪个列表中删除自己。