迭代列表的工作顺序相反但不能通过列表前进(python / pygame)

时间:2017-02-10 19:09:15

标签: python pygame

我使用pygame在python中编写这段代码,在屏幕上显示对象,然后检测碰撞并在发生碰撞时删除对象。

每次发生碰撞时,如果我的代码都是这样编写的,我会收到此错误:

代码:

    for i in range(len(asteroids)):
        asteroidObj = asteroids[i]
        asteroidObj['rect'] = pg.Rect((asteroidObj['x'],
                                       asteroidObj['y'],
                                       asteroidObj['width'],
                                       asteroidObj['height']))
        screen.blit(asteroidObj['surf'], asteroidObj['rect'])
        asteroidObj['x']+= asteroidObj['xChange']
        asteroidObj['y']+= asteroidObj['yChange']
        if asteroidObj['rect'].colliderect(shipObj['rect']):
            del asteroids[i]

错误:

    asteroidObj = asteroids[i]
    IndexError: list index out of range

但是,如果我将for循环更改为:

for i in range(len(asteroids)-1, -1, -1):

代码按预期工作,我不再收到错误。

其中一个循环从项目0-49迭代,另一个循环从49-0迭代,所以我很困惑为什么一个有效,一个没有。有谁知道为什么会这样?

1 个答案:

答案 0 :(得分:2)

它只能反向运行,因为您要从列表中删除元素。

例如,假设您有50个小行星,因此您的列表从0到49.小行星range(len(asteroids))发生碰撞,您将其从列表中删除。现在您的列表长度为49(范围从0到48),但i==49已经过评估,在下一次迭代中您将拥有new_asteroids = [] for asteroidObj in asteroids: # Do your stuff here... if not asteroidObj['rect'].colliderect(shipObj['rect']): new_asteroids.append(asteroidObj) asteroids = new_asteroids ,但不再有元素49。当你删除之前的48时它变成了新的48。

如你所知,反过来是一种解决问题的方法,但我建议避免从列表中间删除元素,因为它是O(n)操作。我会做类似的事情:

input_imgs