11

我是编程新手,我正在尝试解决 codingbat.com 问题。我遇到了这个问题:

给定一个数组,计算总和,除非数组中有 13。如果数组中有 13,则跳过 13 和紧随其后的数字。例如 [1,2,13,5,1] 应该产生 4(因为跳过了 13 和 5s)。

这就是我到目前为止所拥有的。我的问题是当有多个 13 时我不知道该怎么办......而且我想有效地学习编码。你们能帮忙吗?(我使用的是 python 3.2)谢谢!

def pos(nums):
    for i in nums:
        if i == 13:
            return nums.index(13)
    return False

def sum13(lis):
    if pos(lis)!= False:
        return sum(lis[:pos(lis)])+sum(lis[pos(lis)+1:])
    else:
        return sum(lis)
4

7 回答 7

11

需要注意的一件棘手的事情是这样的: [1, 13, 13, 2, 3]

2你也需要跳过

def getSum(l):
    sum = 0
    skip = False
    for i in l:
         if i == 13:
             skip = True
             continue
         if skip:
             skip = False
             continue
         sum += i
    return sum

说明

您将逐一浏览列表中的项目

每次你

  • 先检查是否为13,如果是,则标记skipTrue,这样你也可以跳过下一项。
  • 其次,检查 if skipis True,如果是,则表示它是 13 之后的一项,因此您也需要跳过此一项,并且您还需要设置skipback toFalse以免跳过下一项。
  • 最后,如果不是上述任何一种情况,则将值添加到sum
于 2012-06-16T01:11:35.207 回答
6

您可以使用zip函数成对循环这些值:

def special_sum(numbers):
    s = 0
    for (prev, current) in zip([None] + numbers[:-1], numbers):
        if prev != 13 and current != 13:
            s += current
    return s

或者你可以做一个单行:

def special_sum(numbers):
    return sum(current for (prev, current) in zip([None] + numbers[:-1], numbers)
               if prev != 13 and current != 13)

您还可以使用迭代器:

from itertools import izip, chain
def special_sum(numbers):
    return sum(current for (prev, current) in izip(chain([None], numbers), numbers)
               if prev != 13 and current != 13)

( izip中的第一个列表比第二个长,zipizip忽略额外的值)。

于 2012-06-16T01:12:32.967 回答
3

使用 while 循环遍历列表,i手动递增。在每次迭代中,如果遇到 13,则递增i两次;否则,将该值添加到运行总和并增加i一次。

def skip13s(l):
    i = 0
    s = 0
    while (i < len(l)):
        if l[i] == 13:
            i += 1
        else:
            s += l[i]
        i += 1
    return s
于 2012-06-16T01:02:33.607 回答
2

一些 FP 风格:)

def add_but_skip_13_and_next(acc, x):
    prev, sum_ = acc
    if prev != 13 and x != 13:
        sum_ += x
    return x, sum_

filter_and_sum = lambda l: reduce(add_but_skip_13_and_next, l, (0,0))[1]

>>> print filter_and_sum([13,13,1,4])
4
>>> print filter_and_sum([1,2,13,5,13,13,-9,13,13,13,13,13,1,1])
4

此代码适用于任何迭代器,即使它不提供随机访问(直接索引) - 例如套接字:)

单线:)

>>> filter_and_sum = lambda l: reduce(
...     lambda acc, x: (x, acc[1] + (x if x != 13 and acc[0] != 13 else 0)),
...     l, (0,0))[1]
>>> print filter_and_sum([1,2,13,5,13,13,-9,13,13,13,13,13,1,1])
4
于 2012-06-16T05:14:25.253 回答
1

我认为这是最紧凑的解决方案:

def triskaidekaphobicSum(sequence):
    return sum(sequence[i] for i in range(len(sequence))
               if sequence[i] != 13 and (i == 0 or sequence[i-1] != 13))

这在生成器表达式上使用内置 sum() 函数。生成器生成序列中的所有元素,只要它们不是 13,或者紧跟在 13 之后。额外的“或”条件是处理序列中的第一项(没有前一项)。

于 2012-06-16T02:53:22.973 回答
0

您可以使用while循环来处理多个13.

def sum13(lis):
    while pos(lis):
        if pos(lis) == len(lis) - 1:
            lis = lis[:pos(lis)]
        else:
            lis = lis[:pos(lis)]+lis[pos(lis)+1:]

    return sum(lis)
于 2012-06-16T01:05:07.447 回答
0
def skipAndAddFun(inputVal, skipList):
   sum = 0
   for i in inputVal:
        if not i in skipList:
            sum += i
    return sum

用法:

skipAndAddFun([1,2,13,5,1], [13, 5])
4

这个简单的功能将是您问题的通用解决方案。

于 2017-01-08T12:15:47.423 回答