0

We want to write a function that removes all the odd numbers in a list.

This is what I finally tried:

def eliminate(x):
    for i in range(0, (len(x)-1)):
        if x[i] % 2 != 0:
           x.remove(x[i])
    print(x)
eliminate([1,2,5,6])

I get the error: "List index out of range!"

I'd really appreciate it if you could help because it's driving me crazy that I can't figure out what I'm doing wrong. I tried pop and delete methods too. But I don't know what I'm doing wrong here. It's definitely the 4th line, though. Any ideas?!

poke
  • 369,085
  • 72
  • 557
  • 602
Sara
  • 97
  • 6
  • 1
    when you remove an element from the list, you shorten the list, so you end up out of range. – Stael Sep 25 '17 at 08:45
  • 1
    You shouldn't iterate over a list and delete its elements at the same time. If you have 5 cookies and eat the 2nd cookie then the next one is 3 out of 4 that are left. And then you run to 'cookies out of range' because you don't have 5 of them anymore. Solution: create a new list instead, that consists of 4 cookies only. `if x[i] % 2 != 0 new_list.append(x[i])`. – Tom Wojcik Sep 25 '17 at 08:46
  • That makes sense! Thanks a lot! I was trying to stick with one list, but making another list makes it easier! However, is there probably a way to adapt the iteration length to the list getting shorter? Thanks a lot for your help! – Sara Sep 25 '17 at 08:50

1 Answers1

-1

in python, whenever you find yourself doing for i in range(len(x)): you normally aren't doing things the easiest way.

you could do basically the same thing a few different ways, eg:

x = [1,2,5,6]

for i in x:
    if i % 2 == 1:
        x.remove(i)

print x

as you can see, you don't need the indexes to do this, the for loop pulls the items out of the list directly.

EDIT - apparently this doesn't work in a general case because python edits the list. seems like .remove just isn't a very good way to do this.

another option would be to use a list comprehension:

x = [1,2,5,6]

rem = [i for i in x if i % 2 == 0]

print rem

or you could use filter (but i wouldn't because for no particular reason I don't really like filter.)

Stael
  • 2,619
  • 15
  • 19
  • 1
    Don’t do this, this has the same problem as any other “remove while iterating a list” solution. For an input `x = [1, 3, 2]` this also breaks. – poke Sep 25 '17 at 08:52
  • 1
    @poke, huh, I thought it loaded the whole list into memory before iterating. TIL. – Stael Sep 25 '17 at 08:53
  • The list is already “in memory” but iterators will operate on the list itself, so by modifying it, you are messing with the iteration state. You would need to create a copy of the list for that to work. – poke Sep 25 '17 at 08:55