2016-11-26 4 views
2

入力リストの累積合計、累積積、最大値、最小値を返す関数をコーディングする必要があるmoocに代入があります。
コースのこの部分は関数型プログラミングに関するものでしたので、他の方法を使用することはできますが、私はこれをすべて使いたいと思っていました。
だから私はこれを試してみました:関数リストと引数のマップ:アンパックの難易度

from operator import mul 
from itertools import repeat 
from functools import reduce 
def reduce2(l): 
    print(l) 
    return reduce(*l) 
def numbers(l): 
    return tuple(map(reduce2, zip([sum, mul,min, max], repeat(l,4)))) 
l=[1,2,3,4,5] 
numbers(l) 

私の問題は、それが動作しないということです。 zipはマップ内で使用すると1つのオブジェクトしか渡されず、zipをアンパックすると(関数と引数リストl)の4つのタプルが得られますので、reduce2を定義していますので、動作しませんでした。
Pythonは型エラーを返します:int 'オブジェクトは反復可能ではありません
reduce2(l [0]、l [1])を使用することができますが、それでも同じエラーがあります。
ここではPythonの動作を理解していません。 返り値reduce(l)を使用するだけで、TypeErrorが返されます。予想される引数が2つ以上の場合、1を返します。

ここでは何が起こっていますか?どうすればそれを動作させることができますか? ご協力いただきありがとうございます。

答えて

3

事実上、次のようなコードを実行しようとしている。

xs = [1, 2, 3, 4, 5] 
reduce(sum, xs) 

しかしsumは反復可能を取り、reduceを経由して直接使用すると、実際には互換性がありません。代わりに、2つの引数をとり、それらの合計を返す関数が必要です。これはmulに類似した関数です。あなたはoperatorからそれを得ることができます。

from operator import mul, add 

それからちょうどあなたのプログラムにaddsumを変更します。

ところで、関数型プログラミングの変数命名規則は実際には涼しいものがあります.xとそのリストはxsです。読みにくいlという変数名よりはるかに優れています。また、単数形/複数形を使用して、スカラー値を扱っているのか、コレクションを扱っているのかを伝えます。

+0

命名規則に関する正確さに感謝します。私はそれを知らなかった。addのためにうまくいっていますが、実際には合計はreduceと冗長ですが、今は理解しています。 –

2

FMc answer'sは、コードのエラーを正しく診断します。私はちょうどあなたのmap + zipのアプローチにいくつかの選択肢を追加したいです。 1については

、代わりにreduceの特別バージョンを定義するのは、この目的のために特別に設計されて代わりにmapitertools.starmap、使用することができます。しかし

def numbers(xs): 
    return tuple(starmap(reduce, zip([add, mul, min, max], repeat(xs)))) 

を、さらに良くはしばしば無視使用することですmapvariadic versionの代わりに、手動でビュン引数:

def numbers(xs): 
    return tuple(map(reduce, [add, mul, min, max], repeat(xs))) 

それは本質的zipを行いますあなたのための。関数型プログラミングに関しては、mapのこのバージョンは、HaskellのzipWith関数に類似しています。

+0

私はstarmapを知っていましたが、それについては考えていませんでした。一方、このバージョンの地図は私には分かりませんでした。私はあなたの答えがより多くupvoted得ることを願っています。私は彼が最初に答えたように私はFMcの答えを受け入れるだろうが、あなたのものも賞賛に値する。 –