web-dev-qa-db-ja.com

itertools.accumulate()とfunctools.reduce()

Python 3.3、 itertools.accumulate() では、通常、指定された反復可能オブジェクトに加算演算を繰り返し適用しますが、関数の引数をパラメーターとして受け取ることができるようになりました。これは、 functools.reduce() と重複していることを意味します。ざっと見てみると、2つの主な違いは次のようになります。

  1. accumulate()はデフォルトで合計になりますが、追加の初期条件を明示的に指定することはできません。一方、reduce()はデフォルトでどのメソッドにも設定されませんが、1 /で使用するための初期条件を指定できます。 0要素シーケンス、および
  2. accumulate()が最初に反復可能を取り、reduce()が最初に関数を取ります。

2つの間に他の違いはありますか?それとも、これは、最初は異なる用途が時間の経過とともに収束し始めた2つの関数の動作の問題ですか?

17
JAB

accumulateは以前の結果を保持しているようですが、reduce(他の言語ではfoldとして知られています)は必ずしもそうではありません。

例えばlist(accumulate([1,2,3], operator.add))[1,3,6]を返しますが、単純な折り畳みは6を返します。

また(楽しみのために、これを行わないでください)accumulatereduceで定義できます。

def accumulate(xs, f):
    return reduce(lambda a, x: a + [f(a[-1], x)], xs[1:], [xs[0]]) 
23
Wes

違いはドキュメントで確認できます。 reduceは、シーケンスのsingle結果、合計、積などを返します。 accumulateは、中間結果に対してallのイテレータを返します。基本的に、accumulateは、reduce操作の各ステップの結果に対するイテレータを返します。

5
BrenBarn

itertools.accumulatereduceに似ていますが、値の代わりにジェネレーター*を返します。このジェネレーターは、すべての中間ステップ値を提供できます。したがって、基本的にreduceは、accumulateが与えるものの最後の要素を与えます。

*ジェネレーターはイテレーターのようなものですが、1回だけ繰り返すことができます。

4
iankit