保留函数实现的顺序
问题描述:
所以我有一个数值并且可以应用这两个函数。保留函数实现的顺序
可以说我有一个8号
我想利用它的平方,然后它的日志或第一日志,然后它的平方。
所以我的功能看起来像这样
def transform(value, transformation_list):
# value is int, transformation_list = ["log",square"] or ["square","log"]
# square function and log function
return transformed value
现在,如果转换列表的第一个参数是“方”,第二是“日志”, 那么就应该先执行方,然后登录
但是,如果该列表中的第一个函数是“日志”,第二个“平方”,那么它应该实现第一个日志,然后是方形。
我不想如果:其他有点事情,因为它会变得丑陋,我添加更多的转换 我应该如何设计。
答
像下面的东西应该工作:
import math
func_dict = {'square': lambda x: x**2,
'cube': lambda x: x**3,
'log': math.log}
def transform(value, transformation_list):
for func_name in transformation_list:
value = func_dict[func_name](value)
return value
例如:
>>> transform(math.e, ['cube', 'log', 'square'])
9.0
+0
完美:)谢谢 – Fraz 2012-04-06 18:32:52
答
使用此recipe为功能组合物(或可替代地,使用functional模块),可以构成任意的列表的功能 - 无需将名称作为字符串传递,只需传递以下功能:
class compose:
def __init__(self, f, g, *args, **kwargs):
self.f = f
self.g = g
self.pending = args[:]
self.kwargs = kwargs.copy()
def __call__(self, *args, **kwargs):
return self.f(self.g(*args, **kwargs), *self.pending, **self.kwargs)
def transform(value, transformation_list, inverted=False):
lst = transformation_list if inverted else reversed(transformation_list)
return reduce(compose, lst)(value)
现在你可以调用transform
这样的:
from math import *
value = 2
transformation_list = [sin, sqrt, log]
transform(value, transformation_list)
> -0.047541518047580299
和上面的将相当于log(sqrt(sin(2)))
。如果您需要反转的功能应用的目的,例如sin(sqrt(log(2)))
,那么这样做:
transform(value, transformation_list, inverted=True)
> 0.73965300649866683
此外,您还可以在线定义功能。例如,F.J的例子看起来像这样使用我的实现:
transform(e, [lambda x:x**3, log, lambda x:x**2])
> 9.0
是否需要转换列表是一个字符串列表?你可以传递一个函数列表('from path import log; def square(x):return x * x; transform(8,[log,square])')。 – delnan 2012-04-06 18:18:33
你可以把它写成解决方案并解释一下吗?它不一定是一个清单.. ?? – Fraz 2012-04-06 18:19:53
这可能不是答案,但我的观点是:通过传递函数列表,您可以通过传递函数列表,而不是传递字符串列表,从而使事情变得更容易,更具可扩展性。 – delnan 2012-04-06 18:21:27