2012-04-06 66 views
2

所以我有一个数值并且可以应用这两个函数。保留函数实现的顺序

可以说我有一个8号

我想利用它的平方,然后它的日志或第一日志,然后它的平方。

所以我的功能看起来像这样

def transform(value, transformation_list): 
    # value is int, transformation_list = ["log",square"] or ["square","log"] 
# square function and log function 
return transformed value 

现在,如果转换列表的第一个参数是“方”,第二是“日志”, 那么就应该先执行方,然后登录

但是,如果该列表中的第一个函数是“日志”,第二个“平方”,那么它应该实现第一个日志,然后是方形。

我不想如果:其他有点事情,因为它会变得丑陋,我添加更多的转换 我应该如何设计。

+3

是否需要转换列表是一个字符串列表?你可以传递一个函数列表('from path import log; def square(x):return x * x; transform(8,[log,square])')。 – delnan 2012-04-06 18:18:33

+0

你可以把它写成解决方案并解释一下吗?它不一定是一个清单.. ?? – Fraz 2012-04-06 18:19:53

+1

这可能不是答案,但我的观点是:通过传递函数列表,您可以通过传递函数列表,而不是传递字符串列表,从而使事情变得更容易,更具可扩展性。 – delnan 2012-04-06 18:21:27

回答

2

像下面的东西应该工作:

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

2

使用此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