前言:
近几年,python语言的流程程度可谓突飞猛进,特别是随着AI的兴起,python已经在2017年由“IEEE Spectrum”发布的语言排行榜中,位居榜首。
我有一个坏毛病,没有对python语言进行系统的学习,很多封装的用法仍尚未熟悉。因此!!!经常以“写C++的思想来写pyhon”???什么意思呢,就是本来python已经封装好一些常见的函数,而且都是考虑过性能优化的,但我却经常用python语言自己写一遍。这种情况下,性能往往很差(相对C++),而且很没必要。
本文主要根据亲身经历,介绍python字典中的一个细节,时间性能方面的差异,挺多人都有相似的经历。哈哈,这个细节是实习期的时候,大旺兄弟告诉我的。于是,今天花了点时间,做下实验,看看两者在时间性能上的差异。分享给大家了~
dict.keys() 与 dict.get():
需求:字典是很多语言中的一种重要结构,python中的字典也是非常受欢迎。编程的时候,经常需要判断一个key是否存在于某个字典中。我的第一反应是“if target_key in dict_date.keys()”,一句搞定。殊不知,还有另一种方法的性能更优,那就是“dict_date.get(target_key, "None")”。
dict.keys()
Python 字典(Dictionary) keys() 函数以列表返回一个字典所有的键。
dict.get(key, default=None)
Python 字典(Dictionary) get() 函数返回指定键的值,如果值不在字典中返回默认值。
性能比较:dict.get() 更胜一筹
dict.keys() 和 dict.get() 都能够实现“判断一个key是否存在于某个字典中”,但是两者确实存在时间性能上的差异。
1)dict.keys() 函数以列表的形式返回字典中的所有键值,注意,此时是一个列表;然后使用 “key in list” 的方式判断 key 是否存在于字典对应的list中。
2)dict.get(key, default = None) 函数通过哈希搜索的形式直接返回匹配结果,如果字典中有key对应的键,则返回对应的键值;否则,返回default值。因此,速度会快很多。
模拟实验:
字典:{date:weekday},range(19000101, 20200101),总共43829对键值。
分别使用上述两种方法,循环查询1000次,计算总的耗时(微秒-us表示):
PS C:\Users\hcq_lenovo\Desktop> python .\xx.py
dict_date.keys, cost_time_1 = 1222000 us
dict_date.get, cost_time_2 = 2000 us
dict_date.keys, cost_time_1 = 1213000 us
dict_date.get, cost_time_2 = 0 us
dict_date.keys, cost_time_1 = 1178000 us
dict_date.get, cost_time_2 = 1000 us
dict_date.keys, cost_time_1 = 1209000 us
dict_date.get, cost_time_2 = 2000 us
dict_date.keys, cost_time_1 = 1145000 us
dict_date.get, cost_time_2 = 4000 us
上述实验结果表明:dict.get() 比 dict.keys() 在时间性能上快了几百倍的速度。上述实验数据存在时间上的波动,但实验数据都是一样的。每次实验结果都表明 dict.get() 比 dict.keys() 更快~~~
结论:
以后使用python的字典时,如果需要判断一个字典中是否存在给定的key,记得直接使用“dict.get()”,别在使用“if target_key in dict_date.keys()”了。
实践代码:
# -*- coding: utf-8 -*-
#!/usr/bin/python
import datetime
def get_date_dict():
## key: 20180906
## value: 星期四
# num2str_weekday = {
# "1":"星期一", "2":"星期二", "3":"星期三", "4":"星期四",
# "5":"星期五", "6":"星期六", "7":"星期日"
# }
num2str_weekday = {
"1":"Monday", "2":"Tuesday", "3":"Wednesday", "4":"Thursday",
"5":"Friday", "6":"Saturday", "7":"Sunday"
}
dict_date = dict()
begin = datetime.date(1900, 1, 1)
end = datetime.date(2020, 1, 1)
for i in range((end - begin).days+1):
day = begin + datetime.timedelta(days=i)
weekday = str(day.weekday() + 1)
day = day.strftime("%Y%m%d")
dict_date[day] = num2str_weekday[weekday]
return dict_date
## 查询 python 字典中的值
## way-1
def way_keys(dict_date, target_key):
starttime = datetime.datetime.now()
result = "None"
if target_key in dict_date.keys():
result = dict_date[target_key]
endtime = datetime.datetime.now()
cost_time = (endtime - starttime).microseconds
# print("cost_time = {} (s)".format((endtime - starttime).seconds))
return cost_time
## way-2
## dict.get(key, default=None)
def way_get(dict_date, target_key):
starttime = datetime.datetime.now()
result = dict_date.get(target_key, "None")
endtime = datetime.datetime.now()
cost_time = (endtime - starttime).microseconds
# print("cost_time = {} (s)".format((endtime - starttime).seconds))
return cost_time
if __name__ == '__main__':
dict_date = get_date_dict()
cost_time_1, cost_time_2 = 0, 0
target_key = "20180808"
for i in range(1000):
cost_time_1 += way_keys(dict_date, target_key)
cost_time_2 += way_get(dict_date, target_key)
print("dict_date.keys, cost_time_1 = {} us \ndict_date.get, cost_time_2 = {} us".format(
cost_time_1, cost_time_2))