web-dev-qa-db-ja.com

reduce()の問題は何ですか?

python 3.0でのreduce()関数の変更と、それをどのように削除する必要があるかについて、ネット上で多くの白熱した議論があるようです。これがなぜであるかを理解するのに少し困難があります。いろんなケースで使うのは結構理にかなっているんですが、主観的な軽蔑であれば、こんなに大勢の人が気にかけてくれるとは思えません。

何が欠けていますか? reduce()の問題は何ですか?

65
jeremy

グイドが彼の言うように Python 3000でのreduce()の運命 ポスト:

だから今はreduce()です。これは実際に私が常に最も嫌っていたものです。+または*を含むいくつかの例を除いて、重要な関数引数を含むreduce()呼び出しを目にするたびに、ペンと紙をつかむ必要があるためです。 reduce()が何をすべきかを理解する前に、その関数に実際に供給されているものを図に示します。したがって、私の考えでは、reduce()の適用範囲は結合演算子にかなり限定されており、それ以外の場合はすべて、累算ループを明示的に記述する方が適切です。

Functional Programming HOWTO の記事には、紛らわしいreduceの優れた例があります。

次のコードは何をしていますか?

total = reduce(lambda a, b: (0, a[1] + b[1]), items)[1]

あなたはそれを理解することができますが、何が起こっているのかを理解するために式のもつれをほどくには時間がかかります。短いネストされたdefステートメントを使用すると、状況が少し良くなります。

def combine (a, b):
    return 0, a[1] + b[1]

total = reduce(combine, items)[1]

しかし、私が単にforループを使用した場合、それがすべての中で最も良いでしょう:

total = 0
for a, b in items:
    total += b

または、組み込みのsum()とジェネレータ式:

total = sum(b for a,b in items)

Forループのように記述すると、reduce()の多くの使用法がより明確になります。

68
DzinX

reduce()は削除されていません-functoolsモジュールに移動されているだけです。 Guidoの推論は、合計のような些細な場合を除いて、reduce()を使用して記述されたコードは、通常、累積ループとして記述された方が明確であるということです。

34
John Millikin

人々はそれが難読化されたスタイルのプログラミングを奨励し、より明確な方法で達成できる何かをすることを心配しています。

私は自分自身を減らすことに反対しているわけではありません。

8
Eli Bendersky

Reduceが存在する主な理由は、アキュムレーターを使用して明示的なforループを作成しないようにするためです。 pythonには、関数型スタイルをサポートする機能がいくつかありますが、推奨されません。「Pythonic」関数型スタイルではなく「本物の」関数型スタイルが好きな場合は、最新のLISP(Clojure?)または代わりにハスケル。

2
Terminus