为什么我的代码会引发错误?

时间:2017-06-06 17:59:08

标签: python

我正在进行编码练习:给定一个整数序列作为数组,通过从数组中删除不超过一个元素来确定是否有可能获得严格增加的序列。

所以我写了这段代码:

def almostIncreasingSequence(sequence):
    first_list, second_list = sequence, sequence
    for i in range(len(sequence)-1):
        if sequence[i] >= sequence[i+1]:
            first_list.remove(sequence[i])
            second_list.remove(sequence[i+1])
            break

    if first_list == sorted(set(first_list)) or second_list == sorted(set(second_list)):
        return True
    else:
        return False

现在这段代码似乎适用于大多数序列,但特别是这会引发错误:

print almostIncreasingSequence([1,3,2])

错误如下:

Traceback (most recent call last):
  file.py3 on line ?, in getUserOutputs
    userOutput = _runsppge(testInputs[i])
  file.py3 on line ?, in _runsppge
    return almostIncreasingSequence(*_fArgs_lujxeukjlbwc)
  file.py3 on line 7, in almostIncreasingSequence
    second_list.remove(sequence[i+1])
IndexError: list index out of range

我只是不明白列表索引怎么可能超出范围..任何人都有线索?

2 个答案:

答案 0 :(得分:0)

由于您要从正在迭代的同一列表中删除项目

for i in range(len(sequence)-1):
    if sequence[i] >= sequence[i+1]:
        first_list.remove(sequence[i])     #  <-- removing item
        second_list.remove(sequence[i+1])  #  <-- removing item
        break

并且,如评论中所述,first_list, second_list = sequence, sequence不会创建任何新列表。 first_list, second_list,sequence都指向该行之后的完全相同的列表对象。

<强> EDITED

第一次删除后的列表(first_list.remove(sequence[i]))只有一个元素,因此如果当时边缘上的i+1,它就会越界。

考虑像[1, 2, 3, 5, 4]这样的列表。当if位于元素i(i为3)时触发5语句,然后第一次删除(first_list.remove(sequence[i])),在该语句之后,列表具有4个元素[1, 2, 3, 4],下一行尝试访问i+1second_list.remove(sequence[i+1]))处的元素(元素4),因此得到(i为4)超出范围。

答案 1 :(得分:0)

> c:\users\jeffrey\documents\github\wadi\example.py(4)almostIncreasingSequence()
      3     for i in range(len(sequence)-1):
----> 4         if sequence[i] >= sequence[i+1]:
      5             first_list.remove(sequence[i])

ipdb> next
> c:\users\jeffrey\documents\github\wadi\example.py(5)almostIncreasingSequence()
      4         if sequence[i] >= sequence[i+1]:
----> 5             first_list.remove(sequence[i])
      6             second_list.remove(sequence[i+1])

ipdb> first_list
[1, 3, 2]
ipdb> second_list
[1, 3, 2]
ipdb> next
> c:\users\jeffrey\documents\github\wadi\example.py(6)almostIncreasingSequence()
      5             first_list.remove(sequence[i])
----> 6             second_list.remove(sequence[i+1])
      7             break

ipdb> first_list
[1, 2]
ipdb> second_list
[1, 2]
ipdb>

即使我没有执行此行second_list.remove(sequence[i+1]),因为first_listsecond_list指向同一位置。换句话说,我们可以说一个是另一个的别名。因此,如果一个人可以改变,那么second_list也会得到改变。