derek.baxter derek.baxter - 6 months ago 15
Python Question

Python: removing list from inside list results in: IndexError: list index out of range

I'm a mere beginner at python, so bear with me. I seem to be having some trouble when removing one of the lists from inside another list. The code works perfectly fine if there is only one list inside the list, but if there are two lists inside the list the program crashes when deleting one of them.

import pygame
import math

pygame.init()

BLACK = ( 0, 0, 0)
WHITE = ( 255, 255, 255)
GREEN = ( 0, 255, 0)
RED = ( 255, 0, 0)
BLUE = ( 0, 0, 255)

PI = math.pi

size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Arcade game!")

background_image = pygame.image.load("bg_one.jpg").convert()
player_image = pygame.image.load("player.png").convert()
player_image.set_colorkey(BLACK)

click_sound = pygame.mixer.Sound("laser5.ogg")

done = False

clock = pygame.time.Clock()

bullets = []

def create_bullet(mpos):
bullets.insert(len(bullets), [mpos[0]+50, mpos[1]])

while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
click_sound.play()
create_bullet(pygame.mouse.get_pos())

screen.fill(BLACK)
# Hide mouse, etc.
pygame.mouse.set_visible(False)
# Game Logic
player_position = pygame.mouse.get_pos()
x = player_position[0]
y = player_position[1]
if not len(bullets) <= 0:
for i in range(len(bullets)):
if bullets[i][1] < 0:
print (bullets)
bullets.remove(bullets[i])
print (bullets)
else:
bullets[i][1] -= 5
# Drawing code goes here
screen.blit (background_image, [0, 0])
for i in range(len(bullets)):
pygame.draw.ellipse(screen, GREEN, [bullets[i][0], bullets[i][1], 4, 4])
screen.blit (player_image, [x, y])

pygame.display.flip()

clock.tick(60)

print(bullets)
pygame.quit()


EDIT: Forgot to include error. here it is

Traceback (most recent call last):
File "main.py", line 52, in <module>
bullets.remove(bullets.index(i))
ValueError: 0 is not in list

Answer

I see your problem. Here,

for i in range(len(bullets)):
        if bullets[i][1] < 0:
            print (bullets)
            bullets.remove(bullets[i])
            print (bullets)

Let's say you have an array ["a", "b"]. I want to cycle through this array and remove both elements. "a" is at index 0, and "b" is at index 1. Now, I remove "a" from the array, with

array.remove(array[0])

Now, my array just contains ["b"]. However, now "b" is at index zero. But now you're attempting to access element 1 of the array, which no longer exists.

Your problem is that you're trying to cycle through every element in the array, but you're also deleting elements from the array while you do it. This means that you're trying to index into an array that is now shorter than what you originally thought, and also all the indexes are changing.

Try this code instead:

bulletsToRemove = []

if not len(bullets) <= 0:
    for i in range(len(bullets)):
        if bullets[i][1] < 0:
            bulletsToRemove.append(bullets[i])
        else:
            bullets[i][1] -= 5    

for bullet in bulletsToRemove:
    bullets.remove(bullet)