2012-04-06 10 views
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 

ようになり、 それは最初の正方形を実行し、その後

をログに記録します

しかし、そのリストの最初の関数が "log"で2番目の "square"の場合、最初のログを実装してから正方形にする必要があります。

もし私が望んでいないのなら、それは他の変換を追加すると醜いものになるでしょう。 どうすればよいですか?

+3

変換リストは文字列のリストである必要がありますか?関数のリスト( 'path import log; def square(x):return x * x; transform(8、[log、square])')のリストを渡すことができます。 – delnan

+0

あなたは解決策としてそれを書いて、少し説明できますか?それはリストである必要はありません.. ?? – Fraz

+1

これはおそらく答えではありませんが、私の指摘は文字列のリストを渡す代わりに、関数のリストを渡すことで、より簡単で拡張性のあるものにすることができます。 – delnan

答えて

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

2

functionalモジュールを使用して、代替的又は)関数合成のために、このrecipeを使用して、任意のリストを作成することができ関数の名前 - 文字列として名前を渡す必要はなく、単に関数を渡す:

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 
関連する問題