Confession
Confession

Reputation: 25

why list index out of range but it seems ok

Why did I get "list index out of range" when I was trying to run this code

x = 20
l = [[] for i in range(0, x)]
for m in range(x):
    for i in range(len(l)):
        if i != len(l):
            l[i+1].append(m)

Upvotes: 0

Views: 73

Answers (2)

dwb
dwb

Reputation: 2624

I'll address the reason that this:

if i != len(l):

doesn't work.

I'll skip ahead through the loop until we get to m=0 and i=19.

for m in range(x): # m=0 (still on the first loop)
    for i in range(len(l)): # i=19 (the highest index it will reach)
        ...

The line

if i != len(l):

Says: "As long as the current value for i is not 20 (the initial length of the list), then the following code is safe to run".

But what happens when i=19?

The if statement will check if i (19) doesn't equal 20, and since that check is successful the next line of code will then run:

l[i+1].append(m)

With i=19, this will then do the following:

l[i+1].append(m)
# then
l[19+1].append(m)
# then
l[20].append(m)
# then
IndexError: list index out of range

Since 20 is outside of the list's range. The list's indexes only go from 0 to 19!

That is why your check doesn't work.

Upvotes: 0

ShadowRanger
ShadowRanger

Reputation: 155418

for i in range(len(l)): produces 0 to len(l) - 1 inclusive. So i is never equal to len(l), but when it's equal to len(l) - 1, l[i + 1] is trying to access l[len(l)] which is one more than the highest legal index in l (a list's indices run from 0 (inclusive) to its length (exclusive), so the length itself is never a valid index).

Your test should be if i != len(l) - 1: to exclude the case where i + 1 isn't a legal index. Or more simply (and much more efficiently), just limit the range in the first place so you don't need to add 1 and directly skip index 0 as your current code does:

for m in range(x):
    for i in range(1, len(l)):
        l[i].append(m)

Mind you, in this specific circumstance, you could just build the final l with:

l = [[]] + [list(range(20)) for _ in range(1, x)]

or without the possibly overly dense listcomp:

l = [[]]
for _ in range(1, x):
    l.append(list(range(20)))

since that's what your code is doing in a somewhat circuitous way.

Upvotes: 1

Related Questions