IndexError超出范围,但它在范围内

时间:2017-04-27 18:03:36

标签: python list dictionary

ratings_dict是一个字典,格式为:{'userName':[0,0,1,0等]} 我正在尝试访问列表中的每个元素(在字典中)并且它在'如果ratings_dict [name] [i]不是0:'时给我一个特定的错误,并且它表示IndexError:list index out of范围。

编辑:这是我修改后的代码。从traceback中可以看出,ratings_dict ['Martin'] [0]的值为1。 我还修改了我的代码,考虑到你的效率提示.. 我仍然不知所措。

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

输出:

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

2 个答案:

答案 0 :(得分:3)

如果您收到索引错误但不“相信”您应该这样做,只需打印出列表,您就会看到问题。

a = [0]

想象一下,您不知道a是什么,然后运行此代码:

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

然后你会看到

IndexError, list = [0], index = 1

所以问题很明显。如果列表太长而无法打印,则只需打印长度而不是列表。

答案 1 :(得分:0)

正如其他人已经指出的那样,很难说IndexError而不看ratings_dict的原因。最有可能的是,错误发生是因为包含评级的列表对于不同的用户具有不同的长度。您正在使用len(ratings_dict[Names[0]])计算长度,IndexError是与第一个(即第0个用户)对应的列表的长度。如果第二个用户的列表长度较短,那么您将获得ratings_dict = {"martin" : [1, 4, 3, 4, 5], "tom" : [0, 1, 2, 1, 5], "christina" : [0, 0, 2, 2, 3], }

更详细地说,这就是我的意思。假设您的ratings_dict如下:

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

我们使用以下函数(我基本上简化了你的函数)

IndexError

然后我们得不到calculate_average_rating(ratings_dict) [0.3333333333333333, 1.6666666666666667, 2.3333333333333335, 2.3333333333333335, 4.333333333333333]

ratings_dict

但是,如果我们Christina已经审阅了另一本书,ratings_dict = {"martin" : [1, 4, 3, 4, 5], "tom" : [0, 1, 2, 1, 5], "christina" : [0, 0, 2, 2, 3, 6], } 看起来如下:

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

然后运行该函数会产生一个IndexError:

Class

这是因为不同用户的列表长度不相同。

稍微偏离主题,使用大写字母来启动变量名称被认为是不错的做法,因为它可能会被混淆为Names。有关详细信息,请参阅PEP8。因此,请考虑将names更改为is not

其次,您不应使用>>> a = 1000 >>> b = 1000 >>> a is b False 进行比较。在这种特殊情况下,它不会咬你。但在某些情况下,它会。例如:

is

a运算符会比较ba是否是相同的对象,而不是它们的值。在这种情况下,ba is b具有相同值的对象,因此False的评估结果为$attrString = str_replace("+", " ", str_replace("&", "\" ", str_replace("=", "=\"", http_build_query($attrArray)))) . "\"";