Code is being skipped for elements that don't satisfy if statement

Doing a open.kattis.com problem, but the code in my for loop seems to have been coded wrong. My for loop is skipping elements.

I put in a variety of debugging, and tried switching the order around. However, it is apparent that the code is simply skipping elements where x[i] > 0.

    y = int(input())
    x= input().split(' ')
    cont = True
    i = -1
    while i <len(x):
      i += 1
      print(int(x[i])-y)
      x[i] = int(x[i])-y
      print(x)
      if cont == True and x[i]<0:
        x.pop(i)
        continue
      else:
        cont = False

Using below Input:

y =   20
x = 18 35 6 80 15 21

-2
[-2, '35', '6', '80', '15', '21']

-14
['35', -14, '80', '15', '21']

-5
['35', '80', -5, '21']

Then it returns an error:

Traceback (most recent call last):
  File "main.py", line 6, in <module>
    print(int(x[i])-y)
IndexError: list index out of range

4 answers

  • answered 2019-05-15 03:03 King Stone

    for i in range (0, len(x)):
      x[i] = int(x[i])-y
      x.pop(i)
    

    This code can make IndexError: list index out of range because, x.pop() reduce the x list, so x[i] can error

  • answered 2019-05-15 03:08 Y. P

    pop delete the element from the list, so the length is smaller than the original list. But you move the variable i for 0 to length of the original list, as a result index out of range error occurs.

  • answered 2019-05-15 03:41 Ikhide Eboreime

    To fix this simply, after you execute x.pop(), decrease i by 1.

    ...
    x.pop()
    i -= 1
    continue
    ...
    

    After the first pass, 35 became the first number in your list, but your index becomes incremented to 2 on the second pass. So x[i] is x[2] = -14.

    By the time it gets to the end of the list, your list has become too short for the given index resulting in an out of range error.

  • answered 2019-05-15 03:42 Matthieu Oliveira

    The issue you are facing is you are checking x while you are popping off therefore list x is getting smaller while the loop index is larger. Solution:

    y = 20
    x = "18 35 6 80 15 21".split(' ')
    list_of_numbers = range(0, len(x))
    [int(x[number]) for number in list_of_numbers if (int(x[number])-y)> 0]
    
    [35, 80, 21]
    

    Instead of popping off, do the opposite and leverage the power of list comprehensions!