标签归档:dictionary

RSS feed of dictionary

[Python]: 记一次使用 python 字典踩到的坑

[Python]: 记一次使用 python 字典踩到的坑

问题背景

最近在使用 python 做一个数据量很大的统计任务,抽取账号相同的记录,进行统计并排序。代码中使用到了字典,存储账号相关的记录,用账号作为键。

key = msg_id.split("_")[0]
if key  not in alerm_date_dict:
    data = nbClientData()
    data.name = key
    data.succ = cnt_succ_client
    data.fail = cnt_fail_client
    alerm_date_dict[key] = data
else:
    alerm_date_dict[key].succ += cnt_succ_client
    alerm_date_dict[key].fail += cnt_fail_client

包含以上代码的脚本跑了一个小时才把数据全部跑完,很是耗时,但是遍历数据并不应该是性能瓶颈,而且使用 python 的字典存取数据也并不慢, 但就是跑了整整一小时才跑完,是可忍孰不可忍。Stack Overflow 了一下, 原来罪魁祸首是这句代码导致的。

if key not in alerm_date_dict:

问题分析

字典是Python中唯一内建的映射类型。字典中的值并没有特殊的顺序,但是都存储在一个特点的键(key)里。键可以是数字、字符串甚至是元组。用过 python 的朋友都应该了解,判断一个 key 在不在字典或者列表里,使用 in 这个方法挺好用的。

按理说,python 的字典是C语言实现的 哈希表,效率应该不低才对。研究了一阵才发现隐藏了个坑,原来在对字典使用 in 的时候调用的是 dict.keys() 这个函数, 这个函数返回的是一个列表。

>>> newdict = {1:0, 2:0, 3:0}
>>> newdict.keys()
[1, 2, 3]

返回的列表包含了是整个字典的所有键,每次循环都返回十几万的数据,还要在列表里找对应的键,难怪那么慢!

解决办法

找到原因后,修改代码如下:

key = msg_id.split("_")[0]
if alerm_date_dict.get(key) != None:
    data = nbClientData()
    data.name = key
    data.succ = cnt_succ_client
    data.fail = cnt_fail_client
    alerm_date_dict[key] = data
else:
    alerm_date_dict[key].succ += cnt_succ_client
    alerm_date_dict[key].fail += cnt_fail_client

Python 字典(Dictionary) get() 函数返回指定键的值,如果值不在字典中返回默认值。直接操作字典,不会调用 dict.keys(),改完之后执行一两分钟就跑完任务了。

以上

本文链接:/2018/06/25/python/
请尊重作者的劳动成果,转载请注明出处!Sakishum 博客保留对文章的所有权利。