您可以通过列表理解来做到这一点,但考虑到您请求的具体条款,这对我来说更像是生成器的工作。这是一个非常通用的解决方案,应该适用于序列和迭代器。它对传递给它的迭代执行等效的 Haskellscanl
函数,并使用可选的初始值作为最后一个参数。
第一个参数应该是一个函数,它接受两个参数——当前累积状态和序列中的下一项——并返回下一个累积状态。它可能很简单,也可能operator.add
更复杂。
>>> def scan(f, seq, init=None):
... seq = iter(seq)
... state = seq.next() if init is None else init
... yield state
... for i in seq:
... state = f(state, i)
... yield state
累加和(即三角数):
>>> import operator
>>> list(scan(operator.add, range(10)))
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
从不同的初始值开始:
>>> list(scan(operator.add, range(1, 10), 10))
[10, 11, 13, 16, 20, 25, 31, 38, 46, 55]
适用于您的问题:
>>> diffs = [(1, 0), (-1, 1), (1, 3), (1, 3), (-1, 5), (1, 9)]
>>> list(scan(lambda x, y: (x[0] + y[0], y[1]), diffs))
[(1, 0), (0, 1), (1, 3), (2, 3), (1, 5), (2, 9)]
用不同的初始值,只是为了好玩。
>>> list(scan(lambda x, y: (x[0] + y[0], y[1]), diffs, (5, -1)))
[(5, -1), (6, 0), (5, 1), (6, 3), (7, 3), (6, 5), (7, 9)]