Python Forum
Thread Rating:
  • 1 Vote(s) - 2 Average
  • 1
  • 2
  • 3
  • 4
  • 5
error in FOR
#1
I got this code:
import numpy as np
a=np.zeros(1000)
b=list(a)
b.append(1)
c=[]
for i in range(len(b)):
    if b[i]==0:
        del b[i]
        #print(i)
    c=b
Purpose is to delete all zeroes, so there must be only '1' at the end.
Got this error
Traceback (most recent call last):
File "E:/aero/python/circle.py", line 7, in <module>
if b[i]==0:
IndexError: list index out of range
Reply
#2
A question first... is it neccessary for you to use this particular method (looping and checking for each element) of deleting all zeros from the list? It is not the most efficient, and also the way your for loop is constructed is not the most Pythonic. See this.

And about the list index out of range error - you get it because you shorten the list each time you delete an element. So of course at one point "i" will be greater than the list length and you get the error. Where you have "#print(i)" commented, try print(len(b)) instead and you will see what is happening.
Reply
#3
(Jun-21-2018, 06:11 PM)Antigr Wrote: del b[i]
If you delete the item at i, then everything past that index moves over to the new index. So with the next iteration of the loop, i' refers to the item after what you probably expected it to be.

>>> spam = list(range(5))
>>> for ndx in range(len(spam)):
...   print(f"{ndx} => {spam[ndx]}")
...   del spam[ndx]
...
0 => 0
1 => 2
2 => 4
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
IndexError: list index out of range
That's why you're really not supposed to add/remove items from a list while also iterating over that same list. You could instead build a new list with the things you want to keep, or use a while loop instead of a for loop, for example.

>>> spam = [0 for _ in range(5)]
>>> spam.append(1)
>>> spam
[0, 0, 0, 0, 0, 1]
>>> foo = []
>>> for item in spam:
...   if item != 0:
...     foo.append(item)
...
>>> foo
[1]
>>> # or, if you prefer a comprehension...
...
>>> foo = [item for item in spam if item != 0]
>>> foo
[1]
>>> # or, if you prefer functional approaches...
...
>>> foo = list(filter(lambda item: item!=0, spam))
>>> foo
[1]
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020