-1

I created a for loop that calculates the sum of a list with the exception of the integer 13 and the integer that comes after it. My loop works but I do not know why, can anyone help explain?

I have tried to print various parts of the loop to understand what it is doing. It successfully omits the 13 from the sum but I don't understand why the 2 is also getting skipped.

    nums = [5, 13, 2]

    def sum13(nums):
        i = 0
        for elem in nums:
            if elem != 13:
                i = i + elem
            else:
                nums.remove(elem)
        return i

3 Answers3

1

There is no reason to actually remove the value if it's not 13, you can just skip over it.

def sum13(nums):
    i = 0
    skip = False
    for elem in nums:
        if elem != 13 and not skip:
            i = i + elem
        else:
            if skip:
                skip = False # Stop skipping
            else:
                skip = True
    return i

Then sum13([5, 13, 2, 1]) will return 6.

Chrispresso
  • 3,660
  • 2
  • 19
  • 31
1

The better way to do this is to make nums an explicit iterator, and use next to consume a value from it (the next value that should be skipped) when you find a 13.

def sum13(nums):
    BLACKLIST_NUMBER = 13
    total = 0
    iter_nums = iter(nums)

    for num in iter_nums:
        if num == BLACKLIST_NUMBER:
            next(iter_nums, None)  # the None assures safety if 13 is the last number in sequence
        else:
            total += num

    return total
Adam Smith
  • 52,157
  • 12
  • 73
  • 112
0

Your code "works" because you shorten the list and so 2 is never been "seen" by your loop. Do not modify the list you iterate over.

What happens is you loop over [5, 13, 2]:

1st value is 5, 5 is not 13 so it is added
2nd value is 13 and not added, you delete 13 from your list - it becomes [5,2]
3rd value ... is no longer there, list is only 2 long, loop never looks at 2

It is a common misconception, see f.e. my answer from 2 days ago.


You can remember if you need to skip a number:

def sum13(l):
    skip=False
    s = 0
    for i in l:
        if i==13:
            skip = True
        elif skip:
            skip = False
        else:
            s += i
    return s



print(sum13([5, 13, 2, 21]))  # 26
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • That explains why I could never get the 2 to print, thank you I am new to development and python as you can see. I am impressed by the speed of the responses on stack overflow. – datakhalipha Mar 27 '19 at 23:20
  • I will remember to not to modify the list from here on out. Really appreciate the help! – datakhalipha Mar 27 '19 at 23:21