在python中为字典创建默认值

问题描述 投票:13回答:3

让我们有一个方法,会缓存它计算的结果。

"如果 "方法:

def calculate1(input_values):
    if input_values not in calculate1.cache.keys():
        # do some calculation
        result = input_values
        calculate1.cache[input_values] = result
    return calculate1.cache[input_values]
calculate1.cache = {}

"例外 "办法:

def calculate2(input_values):
    try:
       return calculate2.cache[input_values]
    except AttributeError:
       calculate2.cache = {}
    except KeyError:
       pass
    # do some calculation
    result = input_values
    calculate2.cache[input_values] = result
    return result

"gethas "方法:

def calculate3(input_values):

    if not hasattr(calculate3, cache):
        calculate3.cache = {}

    result = calculate3.cache.get(input_values)
    if not result:
        # do some calculation
        result = input_values
        calculate3.cache[input_values] = result
    return result

是否有另一种(更快)方法?哪种方法最快捷?拟态? 你会用哪个?

笔记: 有一个速度的差异。

calculate = calculateX # depening on test run
for i in xrange(10000):
    calculate(datetime.utcnow())

结果 time python test.py:

calculate1: 0m9.579s
calculate2: 0m0.130s
calculate3: 0m0.095s
python coding-style performance
3个回答
25
投票

使用一个 收藏品.defaultdict. 它正是为此目的而设计的。


5
投票

当然,这毕竟是 Python。只要用一个 违约金.


3
投票

好吧,如果你想追忆一些东西,最好使用Memoize类和装饰器。

class Memoize(object):
    def __init__(self, func):
        self.func = func
        self.cache = {}

    def __call__(self, *args):
        if args not in self.cache:
            self.cache[args] = self.func(*args)
        return self.cache[args]

现在定义一些要被备忘的函数,比如说一个键加强函数,它可以完成一个字符串哈希值的100,000个md5sums。

import md5

def one_md5(init_str):
    return md5.md5(init_str).hexdigest()

@Memoize
def repeat_md5(cur_str, num=1000000, salt='aeb4f89a2'):
    for i in xrange(num):
        cur_str = one_md5(cur_str+salt)
    return cur_str

这个 @Memoize 函数装饰器相当于先定义函数,然后再定义 repeat_md5 = Memoize(repeat_md5). 你第一次调用它的特定参数集时,函数需要大约一秒钟的时间来计算;而下一次你调用它的时候,它几乎是瞬时的,因为它从缓存中读取。

至于记忆化的方法;只要你不做一些傻事(比如第一个方法中你做的是 if key in some_dict.keys() 而非 if key in some_dict)应该不会有太大的区别。 (第一种方法很糟糕,因为你先从字典中生成一个数组,然后检查键是否在其中;而不是仅仅检查键是否在dict中(见 像Python爱好者一样编码)). 另外,从本质上来说,捕获异常会比if语句慢(你必须创建一个异常,然后异常处理程序必须处理它;然后你再捕获它)。

© www.soinside.com 2019 - 2024. All rights reserved.