13

2つの引数を持つ次の関数fが与えられた場合、マップをxのみに適用する標準的な方法は何ですか?

def f (x,y):
    print x,y

具体的には、地図を一行に並べて次の操作を行いたいと思います。

list=[1,2,3]
fixed=10
for s in list:
    f(s,fixed)

そのための1つの方法は次のとおりです。

import functools
map(functools.partial(lambda x,y:f(y,x),fixed),list)

より良い方法は何ですか?

4

4 に答える 4

24

まず第一に、ラムダ AND パーシャルを使用する必要はありません - それらは代替手段です:

map(lambda x:f(x,fixed),srclist)

partial次に、引数の名前がわかっている限り、2 番目の引数を でバインドできます。

map(functools.partial(f,y=fixed),srclist)

または、リスト内包表記を使用します。

[f(x, fixed) for x in srclist]
于 2012-04-25T11:46:35.930 に答える
6

2 つの引数を持つ次の関数 f が与えられた場合、map を x のみに適用する標準的な方法は何ですか?

カリー化と部分適用に関するちょっとした議論

FP 用語では、関数f「カリー化されていません」です。概念的には 2 つの引数を取りますが、それらは単一の製品構造にバンドルされています。Python では、常にすべてがカリー化されていません。一度にすべての引数を指定するか、まったく指定しない必要があります。

これを回避するには、さまざまなトリックがありますが、概念的には関数を「カリー化」したいだけです。つまり、変換f(x,y)f(x)は新しい関数を返しますg(y)

デフォルトでカリー化されている言語では、この翻訳を次のように簡単に書くことができます。

-- curry: take a function from (x,y) to one from x to a function from y to z
curry :: ((x,y) -> z) -> (x -> y -> z)
curry f x y     = f (x, y)

したがってcurry、カリーf化された引数とその積の引数を別々に取り、それらがすべて利用可能になったら引数を適用します。反対も非常に簡単です。

uncurry :: (x -> y -> z) -> ((x,y) -> z)
uncurry f (x,y) =  f x y

これは部分適用とどのように関係していますか?

  • カリー化は、1 つの構造体( n -product) 引数を取る関数を取り、 n 個の引数を取る新しい関数を返します。
  • 部分適用は、n 個の引数の関数を取り、それらをk 個の引数に適用して、残りの引数がnk個の関数を生成します。

アンカリー化言語では、各引数を順番に適用できます (たとえば、関数のアリティに関して部分的に)。カリー化された言語では、上記の例のように、最初に関数をアンカリー化するためにいくつかのトリックを実行する必要があります。

部分的な適用は無料なので、デフォルトでカリー化された環境にいる方が柔軟だと思います。このような環境では、データ構造をパイプラインに変更する関数をチェーン化するのが一般的です。たとえば、整数変更のパイプライン:

(+1) . (*2) . (^3) $ 7

部分的に適用され、カリー化されていない関数のチェーンであり、構成され、それぞれが前の関数の出力を操作します。懸念事項を視覚的に分離するので、これは便利です。

于 2012-04-25T14:52:27.990 に答える
5
map(lambda x: f(fixed,x), thelist)

またはmap()、まったく使用しないで、代わりにリスト内包表記を使用してください。

[f(fixed, x) for x in thelist]

PS: 変数名として使用しないでください。listこれは重要な組み込み名 (リスト型) です。

于 2012-04-25T11:46:52.290 に答える
2

どうしたの:

def add(x, y):
    return x + y

l = [1, 2, 3]

from functools import partial
plus10 = map(partial(add, y=10), l)
print plus10

## [11, 12, 13]
于 2012-04-25T14:30:23.893 に答える