在日常开发过程中,我们经常需要判断一个字典dict中是否包含某个键值,最近在开发代码中遇到一个问题,前端调用接口,会出现返回时间比较慢,进行排查分析,定位到主要是在判断一个字典dict是否包含某个键值item,然而我使用的是if item in dict.keys():,而该字典比较大,出现耗时严重的情况,于是改成if dict.has_key(item),速度马上变快了很多。
下面先简单了解一下has_key() 函数的作用
has_key() 函数用于判断键是否存在于字典中,如果键在字典 dict 里返回 true,否则返回 false。
注意:Python 3.X 不支持该方法。python3 去除了has_key()方法,参考:https://docs.python.org/3.1/whatsnew/3.0.html
Python 3.7环境测试:
>>> dict = {'Name': 'Zara', 'Age': 7} >>> print("Value : ",dict.has_key('name')) Traceback (most recent call last): File "", line 1, in AttributeError: 'dict' object has no attribute 'has_key'
从报错信息可以看到,python3.7已经不支持has_key了
Python 3.X 里不包含 has_key() 函数,被 __contains__(key) 替代:
>>> print("Value : ",dict.__contains__('name')) Value : False >>> print("Value : ",dict.__contains__('Age')) Value : True
Python 3.X 里不包含 has_key() 函数之外,在 3.X 中还可以使用 in 操作符:
>>> dict1 = {'name': 'z', 'Age': 7, 'class': 'First'} >>> >>> if "user" in dict1: ... print(dict1["user"]) ... >>> ##由于user键没有,所以输出空 >>> if "name" in dict1: ... print(dict1["name"]) ... z ##输出键name对应的value
那么,下面我们继续探索这三种用法在性能方面上的差别
对字典大小为100到10000的字典分别使用in dict、in dict.keys()和has_key()判断键值是否存在,记录它们的时间消耗,并绘制出时间对比图,代码如下。
import time from matplotlib import pyplot as plt n = 10000 time1 = [] time2 = [] time3 = [] for n in range(100,10100,100): my_dict = {} for i in range(n): my_dict[i] = i start = time.time() for i in range(n): if i in my_dict.keys(): pass end = time.time() print end - start time1.append(end - start) start = time.time() for i in range(n): if my_dict.has_key(i): pass end = time.time() print end - start time2.append(end - start) start = time.time() for i in range(n): if i in my_dict: pass end = time.time() print end - start time3.append(end - start) t = range(100,10100,100) plt.plot(t, time1, label='in keys()') plt.plot(t, time2, label='has_key') plt.plot(t, time3, label='in') plt.legend() plt.show()
执行结果:
由上图可以发现,dict.has_key和in dict要比in dict.keys()快得多,从图二也可以看到,in dict比dict.has_key要稍微快一点。
结论
在判断一个值item是否是某个字典dict的键值时,最佳的方法是if item in dict,它是最快的,其次的选择是if dict.has_key(item),绝对不要使用if itme in dict.keys()。