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

リスト内包表記でこれを行うことができますが、リクエストの特定の条件を考えると、これはジェネレーターの仕事のように思えます。これは、シーケンスとイテレータの両方で機能する非常に一般化されたソリューションです。scanlオプションの初期値を最後の引数として、渡された iterableに対して Haskell の関数と同等の機能を実行します。

最初の引数は、2 つの引数 (現在の累積状態とシーケンス内の次の項目) を取り、次の累積状態を返す関数でなければなりません。それは同じくらい単純かもしれませんし、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 に答える