Collin Jones
Collin Jones

Reputation: 1

IndexError out of range but it Is in range

ratings_dict is a dictionary with the format: {'userName' : [0, 0, 1, 0, etc]} I'm attempting to access each element in the list (in the dictionary) and it is giving me a specific error at 'if ratings_dict[name][i] is not 0:' and it is saying that IndexError: list index out of range.

Edited: This is my revised code. As you can see from the traceback, the value at ratings_dict['Martin'][0] is 1. I have also revised my code in mind of your efficiency tips.. I am still at a loss at what to do.

def calculate_average_rating(ratings_dict):
    ratings = {}
    numBooks = len(ratings_dict)
    print ratings_dict['Martin'][0]
    for i in range(numBooks):
        x = 0
        sum = 0
        numR = 0
        for name in ratings_dict:
            if ratings_dict[name][x] != 0:
                sum = sum + ratings_dict[name][x]
                numR += 1
                x = x + 1
        if numR is 0:
            ratings[i] = 0

        if sum != 0:
            ratings[i] = float(sum) / float(numR)

    return ratings

Output:

1
Traceback (most recent call last):
  File "C:\Users\Collin\Dropbox\Python Files\main.py", line 106, in     <module>
    main()
  File "C:\Users\Collin\Dropbox\Python Files\main.py", line 103, in main
    print calculate_average_rating(ratingsDict)
  File "C:\Users\Collin\Dropbox\Python Files\main.py", line 10, in     calculate_average_rating
    if ratings_dict[name][x] != 0:
IndexError: list index out of range

Upvotes: 0

Views: 1727

Answers (2)

Dibya Chakravorty
Dibya Chakravorty

Reputation: 96

As others have already pointed out, it is very hard to say what is causing the IndexError without looking at ratings_dict. Most likely, the error is happening because the list containing the ratings has different length for different users. You are calculating the length using len(ratings_dict[Names[0]]), which is the length of the list corresponding to the first (i.e. 0th user). If the second user's list has a shorter length, then you will get an IndexError.

In more detail, here's what I mean. Suppose your ratings_dict is as follows:

ratings_dict = {"martin" : [1, 4, 3, 4, 5],
                "tom" : [0, 1, 2, 1, 5], 
                "christina" : [0, 0, 2, 2, 3],
                }

and we use the following function (I basically simplified your function a little bit)

def calculate_average_rating(ratings_dict):
    names = [key for key in ratings_dict]
    numBooks = len(ratings_dict[names[0]])
    ratings = []
    for i in range(numBooks):
        total = 0
        for name in names:
            if ratings_dict[name][i] != 0:
                total = total + ratings_dict[name][i]

        ratings.append(float(total) / len(names))

    return ratings

then we get no IndexError.

calculate_average_rating(ratings_dict)
[0.3333333333333333,
 1.6666666666666667,
 2.3333333333333335,
 2.3333333333333335,
 4.333333333333333]

However, if we Christina has reviewed an additional book and ratings_dict looks as follows:

ratings_dict = {"martin" : [1, 4, 3, 4, 5],
                "tom" : [0, 1, 2, 1, 5], 
                "christina" : [0, 0, 2, 2, 3, 6],
                }

then running the function gives an IndexError:

calculate_average_rating(ratings_dict)
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-23-1ad9c374e8d8> in <module>()
----> 1 calculate_average_rating(ratings_dict)

<ipython-input-14-080a1623f225> in calculate_average_rating(ratings_dict)
      6         total = 0
      7         for name in names:
----> 8             if ratings_dict[name][i] != 0:
      9                 total = total + ratings_dict[name][i]
     10 

IndexError: list index out of range

It happens because the lists of different users do not have equal length.

Slightly off topic, it is not considered good practice to use capital letters to start variable names, because it can be confused for being a Class. See PEP8 for more details. Therefore, consider changing Names to names.

Secondly, you shouldn't use is not for doing comparisons. In this particular case, it won't bite you. But in some cases, it will. For example:

>>> a = 1000
>>> b = 1000
>>> a is b
False

The is operator compares whether a and b are the same objects, and not their values. In this case, a and b are different objects with the same value, therefore a is b evaluates to False.

Upvotes: 0

Apollys supports Monica
Apollys supports Monica

Reputation: 3258

If you're getting an index error but don't "believe" that you should be, just print out the list and you will see the problem.

a = [0]

Imagine you didn't know what a was and then ran this code:

for i in range(2):
    try :
        x = a[i]
    except IndexError:
        print('IndexError, list = ' + str(a) + ', index = ' + str(i))

Then you would see

IndexError, list = [0], index = 1

and so the problem is clear. If the list is too long to print nicely, you can simply print the length instead of the list.

Upvotes: 3

Related Questions