这个累计金额有什么问题?

时间:2011-01-30 17:40:11

标签: python

我试图得到[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 个答案:

答案 0 :(得分: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中基于零,所以当您将n[i]i混淆时,您正在访问n[3],而n只会从0变为2。

答案 1 :(得分: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

答案 2 :(得分: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))]

这是恕我直言实施cumsum的Pythonic方式。

但这是一个更实用的实现,它允许你处理(所有)所有类型,其中添加可能有意义。

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))

仍有两个收益率,但恕我直言,它仍然非常可读。现在,实现的重点是iterable的第一个元素的类型决定了如何预期加法与其余元素的行为。

答案 3 :(得分:1)

这是一个足够强大的函数,适用于支持+的任何可迭代对象以及2.3以后的任何Python(只需摆弄printxrange即可构建测试基础结构使用3.x):

Python 2.3.5 (#62, Feb  8 2005, 16:23:02) [MSC v.1200 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> def cumsum(iterable):
...     first = True
...     for v in iterable:
...         if first:
...             tot = v
...             first = False
...         else:
...             tot = tot + v
...         yield tot
...
>>> def squares(start, stop):
...     for i in xrange(start, stop):
...         yield i * i
...
>>> tests = [
...     [],
...     [1],
...     [1, 2],
...     range(7),
...     (0, 1, 2, 3, 4, 5, 6),
...     ['a', 'b', 'c'],
...     [['a'], ['b'], ['c']],
...     (('a', ), ('b', ), ('c', )),
...     squares(1, 5),
...     ]
>>>
>>> for test in tests:
...     print test, list(cumsum(test))
...
[] []
[1] [1]
[1, 2] [1, 3]
[0, 1, 2, 3, 4, 5, 6] [0, 1, 3, 6, 10, 15, 21]
(0, 1, 2, 3, 4, 5, 6) [0, 1, 3, 6, 10, 15, 21]
['a', 'b', 'c'] ['a', 'ab', 'abc']
[['a'], ['b'], ['c']] [['a'], ['a', 'b'], ['a', 'b', 'c']]
(('a',), ('b',), ('c',)) [('a',), ('a', 'b'), ('a', 'b', 'c')]
<generator object at 0x014B6A58> [1, 5, 14, 30]
>>>

答案 4 :(得分:0)

for I in n:
    # I will be an item from n
    y+=I

或您尝试做的事情:

for i in range(len(n)):
    # i is an int that you can index with
    y+=n[i]