dsgfdg
dsgfdg

Reputation: 324

Summing integers in python list but excluding the number 13 and the number directly after it

How would I make a better function than what I have?

def sum13(nums):
    total = 0
    wheresNumAfter13 = nums.index(13) + 1
    numAfter13Value = nums[wheresNumAfter13]
    for num in nums:
        if num != 13:
            total += num
    return total - numAfter13Value

print(sum13([1,2,3,4,5,13,4]))

Upvotes: 1

Views: 4670

Answers (5)

Darsh Shukla
Darsh Shukla

Reputation: 11

You can try this way too:

def The13(l):
    size = len(l)
    bucket = [y for x in range(size) for y in range(x,x+2) if(l[x]==13)]
    return sum([l[x] for x in range(size) if x not in bucket]) 

bucket contains all indexes of element having 13 and the number directly after it

Upvotes: 1

hariK
hariK

Reputation: 3059

def sum13(nums):
    if 13 in nums:
        index13 = nums.index(13)
        del nums[index13:index13 + 2]
        return sum13(nums)
    else:
        return sum(nums)

print(sum13([1,2,3,4,5,13,4]))

Upvotes: 1

Jon Clements
Jon Clements

Reputation: 142206

You can do this without having to use list.index or worrying if 13 is present or not:

from itertools import takewhile, islice

def sum13(iterable):
    it = iter(iterable)
    return sum(takewhile(lambda L: L != 13, it)) + sum(islice(it, 1, None))

This will sum up until, but not including 13, then resume summing from the iterable ignoring the number immediately after 13.

Upvotes: 0

outlyer
outlyer

Reputation: 3943

You can do the sum of the relevant slice, similar to what you're doing, look for the index of 13, and then do the sum for the parts of the list before it and after the next element to 13.

You can also use the built-in sum function on the resulting list of combining both parts:

def sum13(nums):
    wheres13 = nums.index(13)
    return sum(nums[0:wheres13]+nums[wheres13+2:])

Note this solution, like yours, only works for the case where you only have a 13 to exclude in the list.
Also they will fail if the list doesn't contain 13.


Explanation, for an example list like: [1,2,3,4,5,13,4,10]:

  • Look for 13: wheres13 = nums.index(13)
  • Get the part of the list before the index of 13: nums[0:wheres13]. This produces a list like [1,2,3,4,5], i.e. from index 0 to index wheres13 (not including it).
  • Get the part of the list after 13: nums[wheres13+2:]. This produces a list like [10], i.e. from the index of the number after the number after 13 (which has index wheres13 plus 2), to the end of the list.
  • Join both lists: nums[0:wheres13]+nums[wheres13+2:]. This produces a list like [1,2,3,4,5,10]
  • Use python's builtin sum function on the list from the previous point

For completeness, heres a version modified to remove every 13 and next number:

def sum13(nums):
    n=nums
    while 13 in n:
        wheres13 = n.index(13)
        n = n[0:wheres13]+n[wheres13+2:]
    return sum(n)

Upvotes: 3

jme
jme

Reputation: 20745

I'd be tempted to write this as a simple-ish generator comprehension. This works even if there are multiple instances of 13s:

>>> x = [1,1,1,13,99,1,1,13,99,1,13,13,13,1]
>>> sum(cur for cur,prev in zip(x, [None]+x) if 13 not in (cur,prev))
6

Read: sum up all of the numbers cur for which cur or the previous number aren't 13.

Maybe writing it as a generator function is more readable, though:

def exclude_13s(x):
    for cur,prev in zip(x, [None]+x):
        if 13 not in (cur,prev):
            yield cur

So that

>>> sum(exclude_13s(x))
6

Upvotes: 2

Related Questions