私はPythonで次のような関数を書き込もうとしています:
def repeated(f, n):
...
ここf
で、は1つの引数を取りn
、正の整数である関数です。
たとえば、正方形を次のように定義した場合:
def square(x):
return x * x
そして私は電話しました
repeated(square, 2)(3)
これは3、2回二乗します。
私はPythonで次のような関数を書き込もうとしています:
def repeated(f, n):
...
ここf
で、は1つの引数を取りn
、正の整数である関数です。
たとえば、正方形を次のように定義した場合:
def square(x):
return x * x
そして私は電話しました
repeated(square, 2)(3)
これは3、2回二乗します。
それはそれを行う必要があります:
def repeated(f, n):
def rfun(p):
return reduce(lambda x, _: f(x), xrange(n), p)
return rfun
def square(x):
print "square(%d)" % x
return x * x
print repeated(square, 5)(3)
出力:
square(3)
square(9)
square(81)
square(6561)
square(43046721)
1853020188851841
または-lambda
少ない?
def repeated(f, n):
def rfun(p):
acc = p
for _ in xrange(n):
acc = f(acc)
return acc
return rfun
reduce
とランバを使用。パラメータで始まり、呼び出したいすべての関数が続くタプルを作成します。
>>> path = "/a/b/c/d/e/f"
>>> reduce(lambda val,func: func(val), (path,) + (os.path.dirname,) * 3)
"/a/b/c"
このようなもの?
def repeat(f, n):
if n==0:
return (lambda x: x)
return (lambda x: f (repeat(f, n-1)(x)))
reduce と itertools.repeat を使用する (Marcin が提案したように):
from itertools import repeat
from functools import reduce # necessary for python3
def repeated(func, n):
def apply(x, f):
return f(x)
def ret(x):
return reduce(apply, repeat(func, n), x)
return ret
次のように使用できます。
>>> repeated(os.path.dirname, 3)('/a/b/c/d/e/f')
'/a/b/c'
>>> repeated(square, 5)(3)
1853020188851841
(それぞれインポートos
または定義した後square
)
を使用したレシピは次のreduce
とおりです。
def power(f, p, myapply = lambda init, g:g(init)):
ff = (f,)*p # tuple of length p containing only f in each slot
return lambda x:reduce(myapply, ff, x)
def square(x):
return x * x
power(square, 2)(3)
#=> 81
私はこれを と呼んでいますpower
。なぜなら、これは文字どおり累乗関数が行うことであり、合成が乗算に取って代わるからです。
(f,)*p
すべてのインデックスでp
満たされた長さのタプルを作成します。f
工夫を凝らしたい場合は、ジェネレーターを使用してそのようなシーケンスを生成します (「参考文献」を参照itertools
)。ただし、ラムダ内で作成する必要があることに注意してください。
myapply
一度だけ作成されるように、パラメーター リストで定義されます。
関数合成が必要だと思います:
def compose(f, x, n):
if n == 0:
return x
return compose(f, f(x), n - 1)
def square(x):
return pow(x, 2)
y = compose(square, 3, 2)
print y