Reputation: 1
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
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
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