Search code examples
pythoncoding-styleperformance

Create default values for dictionary in python


Let's have a method that would cache results it calculates.

"If" approach:

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 = {}

"Except" approach:

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

"get/has" approach:

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

Is there another (faster) way? Which one is most pythonic? Which one would you use?

Note: There's a speed difference:

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

Results time python test.py:

calculate1: 0m9.579s
calculate2: 0m0.130s
calculate3: 0m0.095s

Solution

  • Use a collections.defaultdict. It's designed precisely for this purpose.