简体   繁体   中英

Why does my code raise an error?

I am doing a coding exercise: Given a sequence of integers as an array, determine whether it is possible to obtain a strictly increasing sequence by removing no more than one element from the array.

So I wrote this code:

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

Now this code seems to work on most sequences but this one in particular raises an error:

print almostIncreasingSequence([1,3,2])

The error is as following:

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

I just dont understand how the list index could possibly be out of range.. Anyone got a clue?

Since you are removing items from the same list which you are iterating on

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

And, as mentioned in the comments, first_list, second_list = sequence, sequence doesn't create any new lists. first_list, second_list, and sequence all refer to the exact same list object after that line.

EDITED

The list after the first removal ( first_list.remove(sequence[i]) ), has one less element, hence if the i+1 in on the edge at that moment, it would get out of bound.

Think of a list like [1, 2, 3, 5, 4] . The if statement is triggered when i is at the element 5 (i is 3), then the first removal ( first_list.remove(sequence[i]) ) takes place, after that statement, list has 4 elements [1, 2, 3, 4] , and the next line tries to access the element (element 4) at i+1 ( second_list.remove(sequence[i+1]) ), hence it gets (i is 4) out of bound.

> 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>

Even if I didn't execute this line second_list.remove(sequence[i+1]) , because first_list and second_list point to the same location. In other words we can say that one is an alias of the other. So that if one can change then second_list get change also.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM