2

だから私は数値を持っていて、それらの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」で、2番目の引数が「log」の場合、最初にsquareを実行してから、logを実行する必要があります。

ただし、そのリストの最初の関数が「log」で2番目の「square」の場合、最初のlogを実装し、次にsquareを実装する必要があります。

変換を追加すると醜くなるので、次の場合は必要ありません。これをどのように設計すればよいですか。

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 に答える