0

假设我有一组对象,其中包含:(相对变化,变化时间):

(+1,0) (-1, 1) (+1,3) (+1, 3) (-1, 5) (+1, 9)  

现在我想用它们的绝对值替换相对变化,从 0 开始:

(1,0) (0, 1) (1,3) (2, 3) (1, 5) (2, 9)
 0+1   0+1-1  0+1-1+1 ...

做这个的最好方式是什么?是否有一个 Python 函数可以让我

  • 迭代一个(有序的)对象列表
  • 内部存储一个绝对值
  • 从每个对象读取变化,更新内部绝对值
  • 用绝对值代替相对变化
4

2 回答 2

2

以下是如何通过列表理解来做到这一点:

>>> data = [(+1,0), (-1, 1), (+1,3), (+1, 3), (-1, 5), (+1, 9)]
>>> [(sum(x[0] for x in data[:i+1]), data[i][1]) for i in range(len(data))]
[(1, 0), (0, 1), (1, 3), (2, 3), (1, 5), (2, 9)]

或者稍微更有效(不要求sum()每个值):

result = [data[0]]
for change, t in data[1:]:
    result.append((result[-1][0]+change, t))

由于您说这些是对象,因此您可能需要用属性 get 替换索引,例如x[0]insum(x[0] for x in data[:i+1])可能变为x.change.

于 2012-05-22T19:50:54.597 回答
0

可以通过列表理解来做到这一点,但考虑到您请求的具体条款,这对我来说更像是生成器的工作。这是一个非常通用的解决方案,应该适用于序列和迭代器。它对传递给它的迭代执行等效的 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)]
于 2012-05-22T20:37:23.613 回答