很久以前,有人告诉我d = {}try: a = d['a'] # do somethingexcept KeyError: # do something else比a = d.get('a')if a: # do somethingelse: # do something else但是今天,我做了一个简单的测试后,发现结果恰恰相反:import timed = {}n = 0t1 = time.time()for i in range(1000000): try: a = d['a'] except KeyError: n += 1print(time.time() - t1)>>> 0.4676947593688965import timed = {}n = 0t1 = time.time()for i in range(1000000): a = d.get('a') if a is None: n += 1print(time.time() - t1)>>> 0.3045947551727295那为什么会这样呢?在我的想象中,d.get也应该做类似的判断键是否存在于dict中的逻辑。
1 回答
MM们
TA贡献1886条经验 获得超2个赞
当例外情况是不常见情况时,您所学的规则适用。如果您通常要查找该值,那么d['a']
包装在很少调用异常处理机制的try
/except KeyError:
中将会获胜;如果您通常不会找到该值,则抛出和捕获异常的开销将超过使用泛型方法 dispatch ( d.get('a')
) 与更直接的语法支持方法 ( ) 相比更高的相对开销d['a']
。在现代 (3.7+) CPython 中尤其如此,其中方法调用得到了一些额外的优化,减少了d.get('a')
.
正如您在评论中指出的那样,在查找成功的情况下,get
速度保持相同,而未d['a']
使用的except KeyError:
速度明显更快。在许多情况下它也更正确;如果dict
有映射到 的键None
,您get
的基于 的代码将不会区分“键未找到”和“键映射到None
”,这可能是您想要的,但通常不是。
添加回答
举报
0/150
提交
取消