Search code examples
pythonlistobjectvalueerror

How to fix ValueError: <__main__.projectile object at 0x0000019B405CE128> is not in list


I'm pretty new to python and I am trying to make a simple space invaders game using pygame but I keep getting this error whenever I try to pop one of the bullets in the list. I have been able to pop the bullets with other collisions but am unable to get this one to work.

def hitbaricade():
    global bullets, barricades, enemybullets
    for bullet in bullets:
        for barricade in barricades:
            if abs(barricade.x + (barricade.width//2) - bullet.x) < barricade.width//2 + 2 and abs(barricade.y + barricade.height//2 - bullet.y) < barricade.height//2 + 2:
                bullets.pop(bullets.index(bullet)) #this one breaks
                barricades.pop(barricades.index(barricade)) #this one works


    for ebullet in enemybullets:
        for barricade in barricades:
            if abs(barricade.x + (barricade.width//2) - ebullet.x) < barricade.width//2 + 5 and abs(barricade.y + barricade.height - ebullet.y) < defender.height:
                enemybullets.pop(enemybullets.index(ebullet)) #this one breaks
                barricades.pop(barricades.index(barricade)) #this one works

Heres where is setup the bullet list the list is declared as an empty list before this

if keys[pygame.K_SPACE] and bulletDelay > 10 and len(bullets) < 1:
            bullets.append(projectile(defender.x + (defender.width//2), 460, -1, 10))
            bulletDelay = 0

Heres where I setup the barricade list and the list is decared as an empty list earlier as well

def baricadeSetup():
    global barricades
    x = 45
    y = 410
    x2 = x
    width = 5
    height = 5
    loop = 0
    for i in range(0,4):
        for i in range(0,30):
            barricades.append(shield(x,y,width,height))
            loop += 1
            x += 5
            if loop >= 10:
                loop = 0
                x = x2
                y += 5
        x2 += 125
        x = x2
        y = 410
        loop = 0

I was trying to get an output where the item in the list would pop but instead I would get the error: ValueError: <main.projectile object at 0x000002D6982A5F28> is not in list

Here's the full error message: pygame 1.9.6 Hello from the pygame community. https://www.pygame.org/contribute.html Traceback (most recent call last): File "E:\Python\Scripts\Projects\Login System\spaceInvaders.py", line 317, in main() File "E:\Python\Scripts\Projects\Login System\spaceInvaders.py", line 298, in main hitbaricade() File "E:\Python\Scripts\Projects\Login System\spaceInvaders.py", line 250, in hitbaricade bullets.pop(bullets.index(bullet)) #this one breaks ValueError: <main.projectile object at 0x0000012B51DFE2E8> is not in list


Solution

  • The reason is that you pop the same item over and over again. You should move it from the inner loop.

    And you should avoid modifying the list when you are iterating it.

    def hitbaricade():
        global bullets, barricades, enemybullets
        bullets_removed = set()
        barricades_removed = set()
        for bullet in bullets:
            for barricade in barricades:
                if abs(barricade.x + (barricade.width//2) - bullet.x) < barricade.width//2 + 2 and abs(barricade.y + barricade.height//2 - bullet.y) < barricade.height//2 + 2:
                    bullets_removed.add(bullet)
                    barricades_removed.add(barricade)
        bullets = [bullet for bullet in bullets if bullet not in bullets_removed]
        barricades = [barricade for barricade in barricades if barricade not in barricades_removed]
    
        ebullets_removed = set()
        barricades_removed = set()
        for ebullet in enemybullets:
            for barricade in barricades:
                if abs(barricade.x + (barricade.width//2) - ebullet.x) < barricade.width//2 + 5 and abs(barricade.y + barricade.height - ebullet.y) < defender.height:
                    ebullets_removed(ebullet)
                    barricades_removed(barricade)
        enemybullets = [ebullet for ebullet in enemybullets if ebullet not in ebullets_removed]
        barricades = [barricade for barricade in barricades if barricade not in barricades_removed]