所以我有一个数值,可以应用这两个函数。
假设我有一个号码8。
我想取它的正方形然后是它的日志或首先是日志然后是它的正方形。
所以我的功能看起来像这样
def transform(value, transformation_list):
# value is int, transformation_list = ["log",square"] or ["square","log"]
# square function and log function
return transformed value
现在,如果转换列表的第一个参数是“square”而第二个参数是“log”, 然后它应该首先执行square然后记录
但是如果该列表中的第一个函数是“log”而第二个是“square”,那么它应该实现第一个log然后是square。
我不想要if:else有点像因为我会添加更多变换会变得丑陋 我该如何设计呢。
答案 0 :(得分: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
答案 1 :(得分: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