简体   繁体   中英

IndexError: index out of range

I have a loop that runs 16 times because there's 16 lines in the file it reads from, I'm using a loop to, among other things, read the first two characters of the time stamp. But I can't figure out how to keep the n variable from reaching 17. I've tried to use while conditions to limit n to 16 but to no avail. Here is my entire function, I'm trying to animate the path of hurricane Irene as detailed at http://calicoproject.org/Calico_Python_GIS :

def drawIrene(win):
line = Line()
n = 0
for (x,y) in dots:
    time_stamp[n] = time_stamp[n][:2]
    time_stamp[n+1] = time_stamp[n+1][:2]
    time1 = abs(int(time_stamp[n]) - 12)
    time2 = abs(int(time_stamp[n+1]) - 12)
    wait_time = abs(int(time1) - int(time2))
    x, y = ll2xy(x, y)
    c = Circle(Point(x, y), int(eye_size[n]))
    line.append(Point(x,y))
    c.fill = Color(255, 255, 0, 62)
    c.draw(win)
    t = Polygon((x, y), (x+10, y+5), (x+int(movement_speed[n]), y-int(movement_speed[n])/2))
    t.fill = Color("orange")
    t.draw(win)
    print(time1)
    print(time2)
    print()
    #print (wait_time)
    wait(wait_time)
    if n < len(dots):
        n += 1
    else:
        break
line.draw(win)
line.border = 2

The issue is that you're looping over two sequences of the same length, dots and time_stamp . However, you're looking ahead in the time_stamp sequence, accessing both the current item and the next item in order to calculate the wait_time value. This is causing your IndexError on the last pass through the loop, since an n+1 index points off the end of the list.

There are a few different ways to fix this. You could to modify your data structures so that either dots has one fewer element, or so that time_stamp has one more. Or you could simply loop one fewer time, as suggested in the comments.

But I think the best solution will be to change the logic in your loop to calculate wait_time differently on either the first or last cycle. For instance, you might choose to have no delay on the last cycle.

Here's some code that does just that. It special cases the last pass through, where n is equal to len(time_stamp)-1 , and simply sets wait_time to zero in that case. Note that I'm generating n from the built-in enumerate function in the for loop, so it doesn't need to be initialized to zero or updated manually:

for n, (x, y) in enumerate(dots):
    if n < len(time_stamp)-1:
        time_stamp[n] = time_stamp[n][:2]
        time_stamp[n+1] = time_stamp[n+1][:2]
        time1 = abs(int(time_stamp[n]) - 12)
        time2 = abs(int(time_stamp[n+1]) - 12)
        wait_time = abs(int(time1) - int(time2))
    else: # special case n >= len(time_stamp)-1, which should be the last pass
        wait_time = 0
    x, y = ll2xy(x, y)
    c = Circle(Point(x, y), int(eye_size[n]))
    line.append(Point(x,y))
    c.fill = Color(255, 255, 0, 62)
    c.draw(win)
    t = Polygon((x, y), (x+10, y+5),
                (x+int(movement_speed[n]), y-int(movement_speed[n])/2))
    t.fill = Color("orange")
    t.draw(win)
    wait(wait_time)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM