为什么我的嵌套循环会在Python中抛出异常?

时间:2016-08-17 13:27:22

标签: python

这是一个简单的代码,

def door_traversal():
    arr = []
    for i in range(1, 101, 1):
        arr.append(0)
    for i in range(1, 101, 1):
        for j in range(i, 101, i):
            arr[j] = not arr[j]

    count = 0
    for i in range(1, 101, 1):
        if arr[i] == 1:
            count += 1
    return count

我收到以下错误,

arr[j] = not arr[j]
IndexError: list index out of range

当我在调试器中运行代码时,我发现在程序计数器第一次执行内循环后,它从不运行内循环100次。 我是Python的新手,感谢任何帮助。

5 个答案:

答案 0 :(得分:2)

你从1到101访问索引但是列表的第一个索引是0,你应该在范围内迭代i(100)

def door_traversal():
    arr = [0 for i in range(100)]

    for i in range(100):
        for j in range(100):
            arr[j] = not arr[j]

    count = 0
    for i in range(100):
        if arr[i] == 1:
            count += 1
    return count

如果你想使用自定义索引,也许可以使用字典

def door_traversal():
    arr = {}
    for i in range(1, 101, 1):
        arr[i] = 0
    for i in range(1, 101, 1):
        for j in range(i, 101, i):
            arr[j] = not arr[j]

    count = 0
    for i in range(1, 101, 1):
        if arr[i] == 1:
            count += 1
    return count

答案 1 :(得分:2)

Python列表索引始终从零开始。因此,下面创建一个包含100个元素的列表,索引从0到99(从1到100,如您所料):

for i in range(1, 101, 1):
    arr.append(0)

现在,以下内容可以尝试访问索引100处的元素,该元素不存在:

for i in range(1, 101, 1):
    for j in range(i, 101, i):
        arr[j] = not arr[j]

因此例外。

答案 2 :(得分:1)

你的理解中有一些非常根本的错误。

首先,python 中的列表总是以索引0开头。大小为3的列表如下所示:

three = [0, 1, 2]

索引本身就是值。是的,你可以忽略第一个元素,并创建一个如下列表:

names = [None, 'Wayne', 'CodeMonkey', 'King Arthur']

但它有 4 元素。在代码中的任何地方,您都必须对此进行调整。想知道长度吗? len(names) - 1。等等等等。如果您要拆分列表,如果您想要一致行为,则必须为这些列表添加值:

these_names = names[:2]
those_names = [None] + names[2:]

那很痛苦。不要这样做 - 只是习惯了列表中元素的索引意味着列表+ index元素的开头这一事实。因此,列表开头的项目是列表名称,例如arr,加上[0]元素。

在假设其他一切都正确的情况下,您的代码以有效的方式重写。

def door_traversal():                                             
    # If you really want a list with 101 elements,
    # So you can access the last item with `arr[100]` rather than `arr[99]`.               
    # If you're using Python2, `range` is a list                  
    # already.                                                     
    arr = list(0 for _ in range(101))
    # Or use a list comprehension
    arr = [0 for _ in range(101)]

    # There are probably better ways to do this, but it works now 
    # also, no need to provide the step size if it's 1            
    for i in range(1, 101):                                       
        for j in range(i, 101, i):                                
            arr[j] = not arr[j]                                   

    count = 0                                                     
    for i in range(1, 101, 1):                                    
        if arr[i] == 1:                                           
            count += 1                                            
    return count                                                  

print(door_traversal())                                           

此外,我可能会将arr重命名为doorsvisited_doors,如果这是他们所代表的内容。

答案 3 :(得分:0)

在此行中,您可以向arr

添加100个项目
    for i in range(1, 101, 1):
        arr.append(0)

所以你的arr数组是100项。然后在这个循环中:

    for i in range(1, 101, 1):
        for j in range(i, 101, i):
            arr[j] = not arr[j]

你说在1到101之间的i你想要在j上运行内循环。问题是索引在Python中从零开始,因此arr[101]不存在,只有arr[100]如果你想忽略索引零元素,那很好,你可以开始迭代索引为1的数组,但数组中的最后一个元素仍然位于第100位,因为你只在列表中添加了100个项目!

您可以通过以下方式解决此问题:

def door_traversal():
    arr = []
    for i in range(100):
        arr.append(0)

    for i in range(1, 100):
        for j in range(i, 100, i):
            arr[j] = not arr[j]

    count = 0
    for i in range(0, 100):
        if arr[i] == 1:
            count += 1
    return count

答案 4 :(得分:0)

除了索引问题之外,请考虑以下python习语(注释仅用于教学目的):

def door_traversal():
    """got doc?"""  # why does this func. exist?

    arr = [0] * 100  # list concatenation

    for i in range(1, 101, 1):
        for j in range(i, 101, i):
            arr[j] = not arr[j]
    return arr.count(1)  # use the list method