【问题标题】:random "ValueError: list.remove(x): x not in list" error in pygamepygame中的随机“ValueError:list.remove(x):x不在列表中”错误
【发布时间】:2012-04-12 03:14:59
【问题描述】:

所以我有一个用python编写的小游戏,如果你看到我之前的问题你就知道它是一个“太空入侵者”的克隆。

所以现在几乎所有东西都运行顺利,除了偶尔会弹出一个随机错误。这是完全随机的,它可能在发射了一些子弹之后发生,也可能根本不发生。

我有这个代码:

    for bullet in bullets:
        bullet.attack()
        if bullet.posy<=-20:
            bullet_draw=False
        if bullet_draw==True:
            bullet.draw()
        for enemy in enemies:
            if bullet.sprite.rect.colliderect(enemy.sprite.rect):
                enemy.health-=1
                bullets.remove(bullet)
                bullet_draw=False
            else:
                bullet_draw=True

有时它会给我以下错误。

Traceback (most recent call last):
  File "\Programming\space invaders\space.py", line 280, in <module>
    bullets.remove(bullet)
ValueError: list.remove(x): x not in list

请注意,这个错误是完全随机的;即使不是,我也无法追踪它的起源。关于如何消除它的任何帮助?

【问题讨论】:

  • 一般来说,捕获错误然后使用事后调试器 (import pdb; pdb.post_mortem()) 是解决问题的好方法。在开发过程中,我通常在程序的入口点周围有一个包罗万象的 try-except 子句,这样我就可以立即调试甚至无法预料的问题。

标签: python pygame


【解决方案1】:

尝试将其更改为以下内容:

    for bullet in bullets[:]:    # this is changed, iterating over a copy
        bullet.attack()
        if bullet.posy<=-20:
            bullet_draw=False
        if bullet_draw==True:
            bullet.draw()
        for enemy in enemies:
            if bullet.sprite.rect.colliderect(enemy.sprite.rect):
                enemy.health-=1
                bullets.remove(bullet)
                bullet_draw=False
                break            # this is added, prevents multiple removes
            else:
                bullet_draw=True

请注意我添加的两个显示更改的 cmets,break 是必要的,因为一颗子弹可能会击中多个敌人,这会导致 bullets.remove(bullet) 被调用两次,这会导致您看到的回溯。

第一个更改是必要的,因为在迭代时从列表中删除元素可能会导致一些意想不到的后果,因为您最终会在迭代期间跳过一些元素。以下代码说明了这一点:

>>> data = range(10)
>>> for x in data:
...     data.remove(x)
...
>>> data
[1, 3, 5, 7, 9]

尽管代码看起来应该从列表中删除每个元素,但它只会删除所有其他元素,因为列表索引在迭代期间会发生变化。

【讨论】:

    【解决方案2】:

    你的子弹击中了多个敌人。您需要将break 退出enemies 循环。

    【讨论】:

    • 从 OP 正在迭代的列表中删除项目也会导致问题。
    • @DSM:没错,但这很容易处理。 for bullet in bullets[:]:
    • 完成!顺便说一句,continue 紧跟在bullet_draw=True 之后缩进在for bullet in bullets 下,对吧?
    • @IgnacioVazquez-Abrams:当然,但是当我按下回车键时,我没有看到 F.J. 的更新修复了它。 :^)
    猜你喜欢
    • 2018-07-05
    • 2011-09-11
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    • 2019-03-15
    • 2017-03-26
    • 2018-11-06
    • 2017-12-06
    相关资源
    最近更新 更多