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

现在如果转换列表的第一个参数是“square”,第二个是“log”,那么它应该先执行square然后log

但是如果该列表中的第一个函数是“log”和第二个“square”,那么它应该实现第一个 log 然后是 square。

我不想要 if : else 有点东西,因为当我添加更多转换时它会变得丑陋我应该如何设计这个。

4

2 回答 2

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
于 2012-04-06T18:31:34.520 回答
2

使用此方法进行函数组合(或者,使用函数模块),您可以组合任意函数列表 - 无需将名称作为字符串传递,只需传递函数:

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

此外,您可以在线定义函数。例如,使用我的实现,FJ 的示例将如下所示:

transform(e, [lambda x:x**3, log, lambda x:x**2])
> 9.0
于 2012-04-06T18:39:05.900 回答