2

I have a script that searches for the number 13 in a given list. If it finds a 13, it needs to be removed, but I also need to remove the index after it. I got it to find all the 13s and remove them, but I'm not sure of the best way to remove the index after it. I do know I need to remove the index after 13 first because of the shift after removal. Finally I need to return the sum of all the indices, which I have done.

This is a challenge Im doing in Codebat.com, it doesn't allow for importing.

Here is what I have:

def sum13(nums):
    #Return 0 for empty lists
    if nums == '':
        return 0

    #Find 13s, remove next index and then index of 13
    while(True):
        if 13 in nums:
            #remove the index after 13 here
            nums.remove(13)         
        else:
            break

    #Return the sum of all indices.  
    else:
        return sum(nums)

The input is random lists of ints, for example:

sum13([13, 1, 2, 13, 2, 1, 13]) # Expected Outcome: 3
sum13([1, 2, 13, 2, 1, 13])     # Expected Outcome: 4

To get the next index, I've tried variations of nums.index(i+1) in for loops, which only produces errors, and have been experimenting with list comprehensions and enumerations, but I'm not 100% on those yet.

JonnyDoeInWisco
  • 233
  • 1
  • 4
  • 12
  • 1
    What is the expected behavior for multiple 13s in a row? – Alex Taylor Mar 04 '16 at 03:59
  • 1
    Possibly related: you may want to use [for with reversed order to do this safely](http://stackoverflow.com/questions/35618307/how-to-transform-string-into-dict/35618686#35618686). – Ian Mar 04 '16 at 04:03
  • If it goes to the end of the list, just takes off all the 13s, if there is anything after the multiple 13s, it would be just the next index to remove. – JonnyDoeInWisco Mar 04 '16 at 04:05

2 Answers2

4

You will get errors if you try to index past list length, but this can be circumvented by adding an extra element to the list (it can be zero in your case since you are after the sum of all elements):

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

If you want to account for multiple 13's in a row, do it in reverse order:

    for i in reversed(range(len(nums) - 1)):
Selcuk
  • 57,004
  • 12
  • 102
  • 110
  • It works, thanks. To be clear, is this basically making any index that is 13 index 0? – JonnyDoeInWisco Mar 04 '16 at 04:11
  • Basically yes, but you are confusing the term index with value. Index is the position of the value in the list. For example, the index of the first element in the list is `0`, second element is `1` etc. – Selcuk Mar 04 '16 at 04:12
  • 1
    OH, I see. It's changing the actual value of the index to zero, so when it sums up it doesnt add anything. Didn't think of that, thank you. – JonnyDoeInWisco Mar 04 '16 at 04:14
1
def sum13(nums):
    return (sum13(nums[2:]) if nums[0] == 13 else nums[0] + sum13(nums[1:])) if nums else 0

Downside is it doesn't handle multiple 13's in a row. Upside is it doesn't modify it's argument (a good thing) so can also handle readonly data.

cdlane
  • 40,441
  • 5
  • 32
  • 81