Python:数字的部分和

13

你能帮我写一个返回文本文件中数字部分和的代码吗? 我需要导入文本文件,然后编写一个没有工具等的部分和代码。

我的输入:

4
13
23
21
11
输出应为(不带括号或逗号):
4 
17
40
61 
72

我试图在Python中编写代码,但只能计算总和而不是部分和。如果我对生成器使用+=运算符,它会给我一个错误!


1
你想要一个数组结果还是只是打印输出? - BobS
看这里:reduce(lambda c, x: c + [c[-1] + x], [4, 13, 23, 21, 11], [0])[1:] - wonder.mice
7个回答

27

嗯,既然每个人似乎都在提供他们最喜欢的用于解决问题的习语,那么Python 3中的itertools.accumulate怎么样?

>>> import itertools
>>> nums = [4, 13, 23, 21, 11]
>>> list(itertools.accumulate(nums))
[4, 17, 40, 61, 72]

注意:在3.2版本中新增了一个有趣的功能。 :) - Andy Hayden
2
@hayden:在3.3版本中甚至更好。3.2不接受函数参数。 - DSM
我特别喜欢 total = next(it) 如何处理 [] 情况... - Andy Hayden
1
哇,我不知道他们正在添加这个功能。可惜3.3版本将func作为第二个参数 - 我本来期望它与mapreduce保持一致(以及几乎所有其他接受函数作为参数的itertools函数)。 - senderle
输出应该是无括号的,并且由于某些我不知道的原因,我无法导入itertools。还有其他的方法吗? - user1798558
@DSM 我迫不及待了!@senderle 一致性是一个参数,但使用频率是另一个 - 你总是需要一个函数来mapreduce,并且真的没有有意义的默认值,但accumulate通常用于部分求和。 - Karl Knechtel

13

有多种方法可以创建您的部分和序列。我认为最优雅的方法是使用生成器

def partial_sums(iterable):
    total = 0
    for i in iterable:
        total += i
        yield total
您可以这样运行它:
nums = [4, 13, 23, 21, 11]
sums = list(partial_sums(nums)) # [ 4, 17, 40, 61, 72]

编辑若要从文件中读取数据值,您可以使用另一个生成器,并将它们链接在一起。以下是我如何实现:

with open("filename.in") as f_in:
    # Sums generator that "feeds" from a generator expression that reads the file
    sums = partial_sums(int(line) for line in f_in)

    # Do output:
    for value in sums:
        print(value)

    # If you need to write to a file, comment the loop above and uncomment this:
    # with open("filename.out", "w") as f_out:
    #    f_out.writelines("%d\n" % value for value in sums)

这可能是对OP最有用的答案。 - DSM
如果这个答案对你有帮助,你可以通过在左边选择绿色的勾号(请参见此处了解具体操作步骤)来感谢作者。 - DSM

6

numpy.cumsum可以实现你想要的功能。

如果你不使用numpy,你可以自己编写代码实现。

def cumsum(i):
    s = 0
    for elt in i:
        s += elt
        yield s

5
我认为,除非他已经在使用numpy,否则增加对numpy的依赖并不是一个好主意。 - ThiefMaster

2

试试这个:

import numpy as np

input = [ 4, 13, 23, 21, 11 ]
output = []
output.append(input[0])
for i in np.arange(1,len(input)):
    output.append(input[i] + input[i-1])

print output

2

在numpy中使用累计和:

import numpy as np
input = np.array([4, 13, 23, 21 ,11])
output = input.cumsum()

结果:

print output
>>>array([ 4, 17, 40, 61, 72])

或者,如果您需要列表,您可以将输出转换为列表:

output = list(output)
print output
>>>[4, 17, 40, 61, 72]

1

类似这样的东西:

>>> lst = [4, 13, 23, 21 ,11]
>>> [sum(lst[:i+1]) for i, x in enumerate(lst)]
[4, 17, 40, 61, 72]

6
这段代码先计算 sum([4]),然后是 sum([4,13]),接着是 sum([4,13,23]),等等——这样做违背了计算累积和的初衷! - Katriel
7
我不会说这违背了初衷。虽然这种方法计算效率低(复杂度为O(n^2)而非O(n)),但可以得出正确的答案。 - DSM

1

这是使用reduce的替代方案:

nums = [4, 13, 23, 21, 11]
partial_sum = lambda a, b: a + [a[-1] + b]
sums = reduce(partial_sum, nums[1:], nums[0:1])

在lambda中,加号不是同一个运算符,第一个是列表连接,第二个是两个整数的和。虽然Blckknght的方法可能更清晰,但这个方法更短并且适用于Python 2.7。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接