【问题标题】:python: adding/appending dynamic keys:value pairs inside a dynamic dictionarypython:在动态字典中添加/附加动态键:值对
【发布时间】:2023-03-08 09:20:02
【问题描述】:

我想创建一个字典来存储数学函数的名称、输入(单个数字)和结果。

结构应该类似于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 不是字典结构允许的方法。我尝试了各种方法都没有成功。

感谢您的帮助。

【问题讨论】:

  • 旁注:n^2 不会给你平方,而是 n XOR 2。你想要n**2
  • 你试过什么?您可以编辑添加代码并指出问题所在吗?
  • "...我不知道如何追加到字典。似乎追加不是字典结构允许的方法。"您不附加到字典,而是设置 key:value 对。如果你有字典 d 并且想要设置 4:24 对,你可以使用 d[4] = 24

标签: python dynamic dictionary append key


【解决方案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)

【讨论】:

    【解决方案2】:

    您可能还想查看Memoize。有许多可能的实现,其中 3 个在 Python.org wiki 上。即使您编写自己的版本,看看其他人是如何解决问题的也是有帮助的。

    【讨论】:

    • 感谢您引导我阅读该文档。这正是我所需要的。
    【解决方案3】:

    看看这个!!!

    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'}

    【讨论】:

    • 你编辑了你的帖子并修复了一个问题,但是如果它还没有缓存它仍然不会返回结果,只是计算并添加它以备下次使用
    【解决方案4】:

    这是您想要做的简单装饰器版本。

    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)而不是记住调用@ 987654324@.

    您也可以将其作为一个可调用的类装饰器来存储自己的缓存,而不是需要提供对外部缓存字典的引用。我认为这是@Peter Rowell 链接的 memoize 代码 sn-p 使用的方法——直到现在我才知道那个页面或名称。

    【讨论】:

      【解决方案5】:
      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)
      

      【讨论】:

        猜你喜欢
        • 2019-11-21
        • 2019-03-29
        • 2011-11-04
        • 1970-01-01
        • 2012-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-13
        相关资源
        最近更新 更多