Reputation: 29
I am trying to write a function that iterates through a list to return the sum of the integer elements in the list. However if there is a 13 in the list, it needs to exclude the 13 and whatever comes right after it from the sum. So far I have come up with the following code. This works for almost all cases except when there are two 13's back to back. It only excludes the two 13's instead of the two 13's plus whatever is after the second 13. For example, when I call the function with print(sum13([13, 13, 2, 13, 1, 5, 6, 13]))
, instead of giving the output of 11
it gives 13
. Any help is appreciated.
def sum13(nums):
while 13 in nums:
index13 = nums.index(13)
nums = nums[0:index13]+nums[index13+2:]
return sum(nums)
Upvotes: 0
Views: 1962
Reputation: 198436
You can do it functionally:
def sum13(nums):
return sum(current
for current, following
in zip(nums, [None] + nums[:-1])
if current != 13 and following != 13)
"Gimme a sum of all numbers that are not 13, and whose next number is not 13".
Upvotes: 1
Reputation: 934
Try the below. Note that this is using nexted function to remove 13s, or a series of 13s and the number right after
def refine(nums, index_i):
while 13 in nums:
print(nums)
index = len(nums) - nums[::-1].index(13) - 1
if index == index_i -1:
nums = refine(nums[0:index] + nums[index+1:], index)
else:
nums = refine(nums[0:index] + nums[index+2:], index)
return nums
print( sum(refine([0, 13, 1, 2, 3, 4, 13, 13, 7, 13, 13, 5, 6, 13], 0)) )
This will sum only [0, 2, 3, 4, 6]
However, this is assuming you have a small list to manage With large list, you might want to think of the performance of such manipulation
Upvotes: 0
Reputation: 637
Because generators need love too:
l = [13, 13, 2, 13, 1, 5, 6, 13]
def sanitize(list):
il = iter(list)
for e in il:
while e == 13:
e = next(il)
if e != 13:
e = next(il)
yield e
print(sum(sanitize(l)))
The idea being that you clean up your list first and then sum it up.
Upvotes: 0
Reputation: 4155
You could use a slice to determine whether a 13 precedes a number:
def sum13(nums):
sum_ = 0
for index, elem in enumerate(nums):
if 13 not in nums[max(index-1, 0):index+1]:
sum_ += elem
return sum_
The max
is needed only for the first element, being that i-1
would be 0-1
, so the slice would be [-1:1]
, which is empty. You can even cut it down to one line, if you really wanted to:
sum(e for i, e in enumerate(nums) if 13 not in nums[max(i-1, 0):i+1])
Upvotes: 0
Reputation: 86276
The idiomatic way of doing something like this is to keep track of the previous variable, for example:
def sum13(nums):
prev = None
my_sum = 0
for ele in nums:
if ele != 13 and prev != 13:
my_sum += ele
prev = ele
return my_sum
if __name__ == "__main__":
print(sum13([1,2,13,3,4]))
print(sum13([13, 13, 2, 13, 1, 5, 6, 13]))
Result:
7
11
Upvotes: 1