我正在尝试在 python 中编写一个函数,如下所示:
def repeated(f, n):
...
其中f
是一个接受一个参数并且n
是一个正整数的函数。
例如,如果我将 square 定义为:
def square(x):
return x * x
我打电话给
repeated(square, 2)(3)
这将平方 3、2 次。
我正在尝试在 python 中编写一个函数,如下所示:
def repeated(f, n):
...
其中f
是一个接受一个参数并且n
是一个正整数的函数。
例如,如果我将 square 定义为:
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)))
使用名为repeatfunc
执行此操作的 itertools 配方。
给定
def square(x):
"""Return the square of a value."""
return x * x
代码
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]
通过安装> pip install more_itertools
使用 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
)
我认为你想要功能组合:
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
这是一个使用的食谱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
在参数列表中定义,因此它只创建一次。