rscarth
rscarth

Reputation: 85

Python for loop returning IndexError: list index out of range

I have just recently began to learn python. I am trying to find the lowest integer in the digits list. Instead I get this error:

Traceback (most recent call last):
  File "H:/Python/untitled/08_python.py", line 32, in <module>
    if digits[e] < temp:
IndexError: list index out of range

I realize that you can use min(digits) but I thought I would challenge my knowledge so far. I most likely made a simple mistake and am not diagnosing it properly. If I throw 0 in the list everything works fine.

digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

low = 0
temp = 0
for e in digits:
    if digits[e] < temp:
        low = digits[e]
    temp = digits[e]

print(low)

Upvotes: 1

Views: 526

Answers (3)

Martijn Pieters
Martijn Pieters

Reputation: 1124828

You have several problems in your code:

  • You are making the assumption e is an index. It is not, it is the actual value from your digits list. Your list has indices from 0 through to 9, so when e == 10 (the last element) you'll get an IndexError; there is no digits[10].

  • You set temp and low to 0. None of your values in digits are lower than 0 so you'll never find anything where e < temp will be true. You'll need to pick a very high value instead. float('inf') is an artificial 'highest' value (infinity), that works really well for such tests; any integer value is lower than infinity.

  • You don't need both a temp and a low variable. You only need one or the other to test if a later value is lower still.

Working code, then, looks like this:

low = float('inf')
for e in digits:
    if e < low:
        low = e

Upvotes: 2

tzaman
tzaman

Reputation: 47850

for e in digits iterates over the contents of the list directly. You don't need to use digits[e] at that point since e is already the value, not the index. And that's also why it fails, since digits[10] is past the end of your list.

Other minor note - your code will only work with positive numbers since you're starting with low = 0; if the list has negatives only you'll still get 0 as your result.
One way to avoid that by setting it to None at the beginning and checking for that as well:

low = None
for e in digits:
    if low is None or low < e:
        low = e
print(low)

Upvotes: 6

AJNeufeld
AJNeufeld

Reputation: 8705

for e in digits translates roughly as:

for i in range(0, len(digits)):
    e = digits[i]

So your code becomes:

for i in range(0, len(digits)):
    if digits[digits[i]] < temp:

When:

  • i == 0, digits[i] == 1, & digits[digits[i]] == 2
  • i == 1, digits[i] == 2, & digits[digits[i]] == 3
  • i == 8, digits[i] == 9, & digits[digits[i]] == 10
  • i == 9, digits[i] == 10, & digits[digits[i]] raises IndexError

When you add in 0 at the start of the list, then the identity i == digits[i] holds for all indices, and your code doesn't crash, but it is still doing the double indexing, which is not what you want.

Upvotes: 2

Related Questions