2

数学関数の名前、入力 (単一の数値)、および結果を格納する辞書を作成したいと考えています。

構造は次のようなものでなければなりませんcache = {procedure: {input:result}}

i.e.

cache = {'factorial': {4:24, 10:3628800, 20:2432902008176640000},
         'square': {2:4, 5:25, 10:100}
         'sum': {3:6, 5:10, 7:14}}

def factorial(n):
    #print "Running factorial"
    result = 1
    for i in range(2, n + 1):
        result = result * i
    return result

def square(n):
    result = n ^ 2
    return result

def sum(n):
    result = n * 2
    return result

値を格納する数学関数がわからない可能性があるという意味で、キャッシュ辞書を事前に作成したくありません。次に、cached_execution という名前の関数を作成します。この関数は、関数が入力に対して呼び出されたかどうかを最初にキャッシュをチェックし、そうであれば、input:result ペアの値として格納されているものを返します。

そうでない場合は、操作を計算し、それをキャッシュに保存して値を返します。関数がキャッシュに存在する場合は、その下に別のキーと値のペアを作成する必要があります。そうでない場合は、関数名の新しいエントリを作成し、その下に入力/結果のキー/値を保存します。

cached_execution の構造は単純ですが、辞書に追加する方法がわかりません。append は、辞書構造に許可されているメソッドではないようです。私は成功せずにさまざまなことを試みました。

助けに感謝します。

4

5 に答える 5

4

Memoizeも参照してください。いくつかの可能な実装があり、そのうち 3 つが Python.org wiki にあります。独自のバージョンを作成したとしても、他の人がどのように問題を攻撃したかを確認することは役に立ちます。

于 2012-07-14T17:27:57.067 に答える
1
import pprint

class MathFunctions(object)

    def __init__(self):
        self.cache = {}

    def print_cache(self):
        pprint.pprint(self.cache)

    def factorial(self, n):
        #print "Running factorial"
        result = 1
        for i in range(2, n + 1):
            result = result * i
        return result

    def square(self, n):
        result = n ^ 2
        return result

    def sum(self,n):
        result = n * 2
        return result

    def unknown(self,*args, **kwargs):
        return "UNKNOWN"

if __name__ == "__main__":

    m = MathFunctions()

    functions_to_run = [ 'sum', 'square', 'etc' ]
    input_values     = [ 1, 3.3, 9 ]

    for function in functions_to_run:
        for input in input_values:
            result = m.cache.get(function,{}).get(input,None)

            if None == result:
                if None == m.cache.get(function,None):
                    m.cache[function] = {}
                m.cache[function][input] = getattr(m,function,m.unknown)(input)
于 2012-07-14T17:09:54.487 に答える
1

クラスベースのアプローチは次のとおりです。

def factorial(x):
    result = 1
    for i in range(2, x+1):
        result *= i
    return result


def square(x):
    return x**2


class CachedMath:
    def __init__(self):
        """create a cached result of function return values so that
        if the same function is called with the same argument more
        than once, the operation is not repeated

        """
        self.cache = {}

    def execute(self, func, number):
        if func not in self.cache:
            #if the function has never been used before
            #create a spot in the cache for it
            self.cache[func] = {}

        if number in self.cache[func]:
            #if this operation has been done before
            #return the cached result
            return self.cache[func][number]
        else:
            #otherwise perform the operation and store the result in cache
            result = func(number)
            self.cache[func][number] = result
            return result

ops = CachedMath()
print ops.execute(factorial, 10)
print ops.execute(factorial, 10)
print ops.execute(square, 9)

execute メソッドを使用するだけで、新しい関数の新しいキャッシュを追加できます。

クラスを使用したくない場合は、これもうまくいくようです:

def factorial(x):
    result = 1
    for i in range(2, x+1):
        result *= i
    return result

cache = {}
cache[factorial] = {2: 2, 4: 24, 10:362880}
def do_math(func, number):
    if number in cache[func]:
        return cache[func][number]
    else:
        result = func(number)
        cache[func][number] = result
        return result

print do_math(factorial, 10)
print do_math(factorial, 5)
于 2012-07-14T17:32:37.780 に答える
0

これをチェックしてください!!!

cache={}

def factorial(n):
    result=1
    for i in range(2, n+1):
        result+=1
    return result

def square(n):
    return n^2

def sum(n):
    return n*2


def cached_execution(function,n):
    if function in cache.keys():    
        if n in cache[function].keys():
            return cache[function][n]
        else:
            if function=='factorial':
                cache['factorial'][n]=factorial(n)
                return cache['factorial'][n] 
            elif function=='square':
                cache['square'][n]=square(n)
                return cache['square'][n]
            elif function=='sum':
                cache['sum'][n]=sum(n)
                return cache['sum'][n]
    else:
        cache[function]={}
        if function=='factorial':
            cache['factorial']={}
            cache['factorial'][n]=factorial(n)
            return cache['factorial'][n] 
        elif function=='square':
            cache['square']={}
            cache['square'][n]=square(n)
            return cache['square'][n]
        elif function=='sum':
            cache['sum']={}
            cache['sum'][n]=sum(n)
            return cache['sum'][n]
        else:
            cache[function]={}      
            cache[function][n]="Define_function"
            return cache[function][n]


cached_execution('sum',8)
cached_execution('square',7)
cached_execution('sum',5)
cached_execution('factorial',10)
cached_execution('log',10)
print cache

次のように出力されます。{'factorial': {10: 10}, 'sum': {8: 16, 5: 10}, 'square': {7: 5}, 'log': {10: 'Define_function'}

于 2012-07-14T17:21:16.043 に答える
0

これは、やりたいことの単純なデコレータバージョンです。

def cached_execution(cache):
    def cached_exec_decorator(func):
        def check_cache(x):
            try:
                result = cache[func.__name__][x]
            except KeyError:
                result = func(x)
                if func.__name__ not in cache:
                    cache[func.__name__] = {x : result}
                else:
                    cache[func.__name__][x] = result
            return result
        return check_cache
    return cached_exec_decorator

使用例:

cache = dict()

# decorator for caching the function call
# you have to pass it a dict to cache in
@cached_execution(cache)
def square(x):
    print "Square is being evaluated!"
    return n ** 2

print square(5) # "Square is being evaluated!\n25" - square(5) isn't cached
print square(5) # "25" - square(5) is cached
print cache # {'square': {5: 25}}

このメソッドは、最初に説明したメソッドや、これを書いているときに投稿した他の回答のいくつかよりも意味的に少し優れています。キャッシュメカニズムを隠しているため、呼び出すsquare(x)ことを忘れずに呼び出すことができますcached_execution(square, x)

おそらく、外部キャッシュ dict への参照を提供する必要なく、独自のキャッシュを格納する呼び出し可能なクラス デコレーターとしてこれを行うこともできます。これは、@Peter Rowell がリンクした memoize コード スニペットで使用されている方法だと思います。そのページや名前については今まで知りませんでした。

于 2012-07-14T17:49:36.367 に答える