在日常开发过程中,我们经常需要判断一个字典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()。