我試圖用Python語言編寫的函數是這樣的:如何重複功能n次
def repeated(f, n):
...
其中f
是一個函數,它接受一個參數,n
是一個正整數。
例如,如果我定義平方爲:
def square(x):
return x * x
和我稱爲
repeated(square, 2)(3)
這將方3,2次。
我試圖用Python語言編寫的函數是這樣的:如何重複功能n次
def repeated(f, n):
...
其中f
是一個函數,它接受一個參數,n
是一個正整數。
例如,如果我定義平方爲:
def square(x):
return x * x
和我稱爲
repeated(square, 2)(3)
這將方3,2次。
是這樣的?
def repeat(f, n):
if n==0:
return (lambda x: x)
return (lambda x: f (repeat(f, n-1)(x)))
應該這樣做:
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
用於無lambda版本的+1。 – phimuemue
我想你想要的功能組成:
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
請注意OP是要求更高階的函數。您已經創建了一個重複應用相同函數的遞歸函數。不完全相同。 – Marcin
下面是使用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
) - 但注意它必須在lambda內部創建。
myapply
在參數列表中定義,因此它只創建一次。
對於大p來說,這具有顯式構造長度爲n的元組的缺點。 –
@ UweKleine-König是的,這就是爲什麼5年前我提到使用itertools生成器作爲替代方案。 – Marcin
啊對,不好意思,只看着代碼... –
使用reduce
和蘭巴。 構建起與您的參數元組,其次是所有的功能你要撥打:
>>> path = "https://stackoverflow.com/a/b/c/d/e/f"
>>> reduce(lambda val,func: func(val), (path,) + (os.path.dirname,) * 3)
"https://stackoverflow.com/a/b/c"
使用減少和itertools.repeat(如馬辛建議):
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
之後)
有一個itertools配方repeatfunc
執行此操作。
def repeatfunc(func, times=None, *args):
"""Repeat calls to func with specified arguments.
Example: repeatfunc(random.random)
"""
if times is None:
return starmap(func, repeat(args))
return starmap(func, repeat(args, times))
我使用第三方庫,more_itertools
,它可以方便地實現這些食譜(可選):
import more_itertools as mit
list(mit.repeatfunc(square, 2, 3))
# [9, 9]
哪裏是你的問題? –