4

Python での使用について学びたかったmapのですが、Google 検索でhttp://www.bogotobogo.com/python/python_fncs_map_filter_reduce.phpにたどり着きました。

そのページのコードの 1 つは for ループを使用し、mapその for ループ内に興味深い方法で配置しますmap。関数内で使用されるリストは、実際には 2 つの関数のリストを取ります。コードは次のとおりです。

def square(x): 
    return (x**2)

def cube(x):
    return (x**3)

funcs = [square, cube]

for r in range(5):
    value = map(lambda x: x(r), funcs)
    print value

出力:

[0, 0]
[1, 1]
[4, 8]
[9, 27]
[16, 64]

したがって、そのチュートリアルのこの時点で、「そのコードをその場で関数 (ラムダ) で記述できれば、標準関数を使用して記述できる」と考えましたdef。そこで、コードを次のように変更しました。

def square(x): 
    return (x**2)

def cube(x):
    return (x**3)

def test(x):
    return x(r)

funcs = [square, cube]

for r in range(5):
    value = map(test, funcs)
    print value

r最初のコードと同じ出力が得られましたが、変数がグローバル名前空間から取得されたことと、コードが厳密な関数型プログラミングではないことが気になりました。そして、つまずいたところがあります。これが私のコードです:

def square(x): 
    return (x**2)

def cube(x):
    return (x**3)

def power(x):
    return x(r)

def main():
    funcs = [square, cube]
    for r in range(5):
        value = map(power, funcs)
        print value

if __name__ == "__main__":
    main()

このコードをいじってみましたが、問題は function に渡すことdef power(x)です。この関数に渡そうとするさまざまな方法を試しましたが、ラムダにxは list の各反復に変数を自動的に割り当てる機能がありますfuncs

標準関数を使用してこれを行う方法はありますdefか、それとも不可能であり、ラムダのみを使用できますか? 私はPythonを学んでおり、これが私の最初の言語であるため、ここで何が起こっているのかを理解しようとしています.

4

3 に答える 3

4

power()関数内に関数をネストできmain()ます。

def main():
    def power(x):
        return x(r)

    funcs = [square, cube]
    for r in range(5):
        value = map(power, funcs)
        print value

そのためr、周囲のスコープから再び取得されますが、グローバルではありません。代わりにクロージャー変数です。

ただし、 a の使用は、ここで周囲のスコープから挿入して関数に渡すlambda別の方法にすぎません。rpower()

def power(r, x):
    return x(r)

def main():
    funcs = [square, cube]
    for r in range(5):
        value = map(lambda x: power(r, x), funcs)
        print value

これrは、親スコープから取られた非ローカルです!

r2 番目の引数のデフォルト値を使用してラムダを作成できます。

def power(r, x):
    return x(r)

def main():
    funcs = [square, cube]
    for r in range(5):
        value = map(lambda x, r=r: power(r, x), funcs)
        print value

r代わりにデフォルト値として渡されるようになったため、ローカルとして取得されました。しかし、あなたの目的のために、map()実際には違いはありません。

于 2015-03-28T14:57:32.317 に答える
3

カレーは別のオプションです。2 つの引数の関数は、残りの引数を取る別の関数を返す 1 つの引数の関数と同じであるため、次のように記述できます。

def square(x):
    return (x**2)

def cube(x):
    return (x**3)

def power(r):
    return lambda(x): x(r) # This is where we construct our curried function

def main():
    funcs = [square, cube]
    for y in range(5):
        value = map(power(y), funcs) # Here, we apply the first function
                                     # to get at the second function (which
                                     # was constructed with the lambda above).
        print value

if __name__ == "__main__":
    main()

関係をもう少し明確にするために、 type(a, b) -> cの関数 ( type の引数と type の引数を取り、 typeab値を返すc関数) は type の関数と同等a -> (b -> c)です。

同等性に関する追加事項

この等価性の背後にある数学をもう少し詳しく知りたい場合は、代数を少し使ってこの関係を確認できます。これらの型を代数データ型として見ると、任意の関数a -> bを b a に変換し、任意のペア(a, b)を a * b に変換できます。この関係から、関数型は「指数型」、ペア型は「積型」と呼ばれることがあります。ここから、

c (a * b) = (c b ) a

など、

(a, b) -> c  ~=  a -> (b -> c)
于 2015-03-28T19:35:25.933 に答える
1

関数を引数の一部として単に に渡し、必要な組み合わせを作成するためにpower()使用しないのはなぜですか?itertools.product(value, func)

from itertools import product

# ...

def power((value, func)):
    return func(value)

for r in range(5):
    values = map(power, product([r], funcs))
    print values

または、結果を関数でグループ化したくない/必要とせず、代わりにフラットリストが必要な場合は、次のように簡単に実行できます。

values = map(power, product(range(5), funcs))
print values

注: シグネチャは、 andに自動的にアンパックされる単一の 2 タプル引数を受け入れるようにpower((value, func))定義します。power()valuefunc

と同等です

def power(arg):
    value, func = arg
于 2015-03-28T15:36:26.987 に答える