1

I was practicing from coding bat. The question was to create a function that will return the sum of numbers in a list. However, if a number is 13 , it will be skipped and the number next to it will also be skipped. I have tried it but I am getting an error that says ‘list index out of range’. I have put the code I tried to use below. Please help. I do not understand why it doesn’t work. Edit: I tried something a bit more different and it’s given below . I still get list index out of range. However, I am not removing anything from the main list. Why doesn’t this work now? Edit 2: Tried something else. Also given below . For an input like [1,2,13,2,1,13] I am getting 6 , which is clearly wrong.

def sum13(nums):
    for i in range(len(nums)):
       if nums[i] == 13:
          nums.remove(nums[i])
          nums.remove(nums[i+1])
    result = sum(nums)
    return result 


def sum13(nums):
    result = sum(nums)
    for x in range(len(nums)):
        if nums[x] == 13:
           result -= nums[x]
           result -= nums[x+1]
    return result 

def sum13(nums):
    result = sum(nums)
    for x in range(len(nums)):
        if nums[x] == 13:
           result -= nums[x]
           if nums[x] != nums[-1]:
              result -= nums[x+1]
    return result 
Glenn Ferrie
  • 10,290
  • 3
  • 42
  • 73
Bum Bum
  • 49
  • 6
  • 2
    Mutating list while iterating is the main problem. It can have undesired results. – Ch3steR Apr 20 '20 at 06:14
  • Could you please explain a bit more. I am a complete beginner. – Bum Bum Apr 20 '20 at 06:15
  • This can be helpful to overcome the problem https://stackoverflow.com/questions/1207406/how-to-remove-items-from-a-list-while-iterating – Ch3steR Apr 20 '20 at 06:20
  • you are getting an error because these two statements are out of sequence: `result -= nums[x]` and `result -= nums[x+1]` -- remove `x+1` first. The length of the array changes when you remove elements. Start from the item closest to the end of the list. – Glenn Ferrie Apr 28 '20 at 01:39

7 Answers7

2

Do not remove elements in a list while you're iterating over it. It will give you unintended results. In fact, in the comments above this post have alluded to the following post: strange result when removing item from a list. Have a read and make sure you understand it before you proceed.

However to solve your immediate problem, do not remove the items inside the loop. Literally just skip them instead. So you'll want to jump over the i and i+1th element but because range provides an object that you're iterating over, try using a while loop instead, followed by a continue statement so you can avoid summing over the elements that are not intended:

def sum13(nums):
    i = 0
    result = 0
    while i < len(nums):
       if nums[i] == 13:
          i += 2
          continue
       result += nums[i]
       i += 1
    return result
rayryeng
  • 102,964
  • 22
  • 184
  • 193
1

The problem is that you're changing objects in a list while you read the list in a loop.

Noah.Ehrnstrom
  • 172
  • 1
  • 12
1

You are changing the list while you're iterating over it. This causes unexpected behavior from python. Every iteration, i is incremented by 1. However, you are removing items from the list as you iterate, so i will try to iterate up until the original length, and will raise an index error.

TL;DR: Don't change anything you iterate on in the loop!

YonPog
  • 19
  • 2
1

Okay, here's what's happening.

Imagine nums is [1, 13, 7, 4]

while iterating over it, starting with index 0,

nums[0] is 1, which is fine

nums[1] is 13, so it is removed from the list.

now nums is [1, 7, 4]

nums[2] now points to 4, and 7 gets skipped.

To avoid this behaviour, one simple way is to just loop over the array backwards.

def sum13(nums):
    for i in range(len(nums) - 1, -1, -1):
    # ... rest of the code stays same
Tushar Sadhwani
  • 414
  • 4
  • 7
0

Try this:

def sum13(nums):
    result = sum(nums)
    for i in range(len(nums)-1):
       if nums[i] == 13:
          result -= nums[i]
          result -= nums[i+1]
    if nums[-1]==13:
        result -= 13 
    return result 
Dhaval Taunk
  • 1,662
  • 1
  • 9
  • 17
0

Considering that even if the last number is 13, it should be skipped then:

 def sum13(nums):
    leng = len(nums)
    for i in range(leng):
       if nums[i] == 13:
          nums[i]=0
          if i<leng-1:
             nums[i+1]=0
    result = sum(nums)
    return result
Prudhvi
  • 1,095
  • 1
  • 7
  • 18
Manik
  • 1
  • 2
0

You can avoid using indices completely, using a logic closest to the problem description, and calculating the total in one pass:

data = [1, 2, 13, 5, 14, 13]

total = 0
skip = False

for n in data:
    if n == 13:
        skip = True
    elif not skip:
        total += n
    else:
        # we skipped the value in this loop, we won't skip the next one
        skip = False

print(total)
# 17
Thierry Lathuille
  • 23,663
  • 10
  • 44
  • 50
  • Thank u for your help. I tried something a bit different and put it in the question. Do you why it doesn’t work still? :( – Bum Bum Apr 20 '20 at 06:57
  • Question - does the *end* of your list have the value 13 in it? If so, what do you think is going to happen when you try to access the value next to the end when it doesn't exist? To solve it, think about your `for` loop and where exactly you need to stop iterating. – rayryeng Apr 20 '20 at 07:09
  • Ok I understood the problem . I’ll try to make a new solution . I’ll post it in 5 mins. Thank you for your help rayryeng – Bum Bum Apr 20 '20 at 07:16
  • @BumBum All you need is a single `if` statement where you're looking at the `x+1` element. – rayryeng Apr 20 '20 at 07:19
  • Is it possible to use two if statements after one another . Like I want to check if something in a data is true . If true then I want to check if something else is also true within the same data – Bum Bum Apr 20 '20 at 07:23
  • Change `if nums[x] != nums[-1]:` to `if x != len(nums) - 1:` – rayryeng Apr 20 '20 at 07:33
  • I tried it and put it in question. Still doesn’t work. – Bum Bum Apr 20 '20 at 07:38
  • It does for me... I'll end my help here. Good luck! – rayryeng Apr 20 '20 at 07:39