[英]Create default values for dictionary in python
讓我們有一個方法來緩存它計算的結果。
“如果”方法:
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
“獲取/擁有”方法:
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
還有另一種(更快)的方法嗎? 哪個是最pythonic的? 你會用哪一種?
注意:有速度差異:
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
使用collections.defaultdict 。 它正是為此目的而設計的。
當然; 畢竟這是 Python:只需使用defaultdict 。
好吧,如果你想記住一些東西,最好使用 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
而不是if key in some_dict
if key in some_dict.keys()
的第一種方法),就不會有太大的區別。 (第一種方法不好,因為你首先從字典中生成一個數組,然后檢查鍵是否在其中;而不是僅僅檢查鍵是否在字典中(參見像 pythonista 一樣的編碼))。 此外,捕獲異常的速度自然比 if 語句慢(您必須創建一個異常,然后異常處理程序必須處理它;然后您才能捕獲它)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.