这个累积和哪里出错了?

4 投票
5 回答
7773 浏览
提问于 2025-04-16 10:54

我想得到的结果是 [1,3,6]。我是不是漏掉了什么很明显的东西?我遇到的错误是:IndexError: list index out of range

def cumulative_sum(n):
    cum_sum = []
    y = 0
    for i in n:
        y += n[i]
        cum_sum.append(y)

    print cum_sum

a = [1,2,3]
cumulative_sum(a)

5 个回答

6

这里有一个简单的基于生成器的实现:

def cumsum(seq):
    s= 0
    for c in seq:
       s+= c
       yield s

print [c for c in cumsum(range(7))]
print [c for c in cumsum((0, 1, 2, 3, 4, 5, 6))]

在我看来,这是一种相当符合Python风格的实现方式。

但是这里有一个更实用的实现,它可以处理几乎所有可以进行加法运算的类型。

def cumsum(seq):
    s= seq[0]
    for k in xrange(1, len(seq)):
        yield s
        s= s+ seq[k]
    yield s

print [c for c in cumsum(range(7))]
print [c for c in cumsum((0, 1, 2, 3, 4, 5, 6))]
print [c for c in cumsum(['a', 'b', 'c'])]
print [c for c in cumsum([['a'], ['b'], ['c']])]
print [c for c in cumsum((('a', ), ('b', ), ('c', )))]

所以这些例子都按预期的方式运行,而这在更“Pythonic”的版本中并不成立。你可以自己试试,找出不同表现的原因。

更新:
根据评论,一个更通用的cumsum实现可以是:

def cumsum(iterable):
    iterable= iter(iterable)
    s= iterable.next()
    yield s
    for c in iterable:
        s= s+ c
        yield s

tests= [
    [],
    [1],
    [1, 2],
    range(7),
    (0, 1, 2, 3, 4, 5, 6),
    ['a', 'b', 'c'],
    [['a'], ['b'], ['c']],
    (('a', ), ('b', ), ('c', )),
    xrange(7),
    ]

for test in tests:
    print test, '=> ', list(cumsum(test))

仍然有两个生成值,但在我看来,它依然非常易读。而且这个实现强调了可迭代对象的第一个元素的类型决定了后面元素的加法运算应该如何进行。

7

问题出在你的循环上:

for i in n:
    y += n[i]

这个 for 循环是遍历 n 的值,而不是索引。你需要把 y += n[i] 改成 y += i

在循环的第三次运行时(当 i 是 3),会出现异常,因为 3 超出了数组的范围(有效的索引是 [0-2])。

如果你想同时遍历索引,可以使用内置的 enumerate 函数:

for i, x in enumerate(n):
    assert n[i] == x
8
def cumulative_sum(n):
    cum_sum = []
    y = 0
    for i in n:   # <--- i will contain elements (not indices) from n
        y += i    # <--- so you need to add i, not n[i]
        cum_sum.append(y)
    print cum_sum

a = [1,2,3]
cumulative_sum(a)

在Python中,数组是从0开始计数的。所以当你把 n[i]i 搞混的时候,其实你是在访问 n[3],但 n 这个数组的有效索引只有0到2,也就是最多只能访问到第三个元素。

撰写回答