首页 > 编程语言 >为啥我的Python这么慢 - 项查找 (二)

为啥我的Python这么慢 - 项查找 (二)

时间:2023-05-07 23:35:15浏览次数:43  
标签:defaultdict 10 Python 为啥 复杂度 python 查找 key 字典


根据那篇文章改了两处写法,如下 (存储于readFaJoin2.py文件中):

from collections import defaultdict

aDict = defaultdict(list)

for line in open("GRCh38.fa"):
    if line[0] == '>':
        key = line[1:-1]
    else:
        aDict[key].append(line.strip())
#----------------------------------------
for key, value in aDict.iteritems():
    aDict[key] = ''.join(value)

比之前提速接近2s。一个是使用了defaultdict初始化字典,另外一个是用iteritems遍历字典,节省近一半的内存。

time python readFaJoin2.py

real    0m49.114s
user    0m38.442s
sys 0m10.565s

defaultdict用在这效果不太明显,之前处理全基因组每个位点数据的频繁存取时,defaultdict在程序无论速度还是写法上都有很大提升。

字典本身还有更多高效用法,可以去参考知乎的那篇文章。这儿介绍的是妙用字典的哈希属性快速查找项。

在生信操作中,常常会在一个大矩阵中匹配已小部分基因或位点,提取关注的基因或位点的信息。最开始的写法是:

targetL = ['a', 'n', 'c', 'd']
if item in targetL:
    other_operations

后来,随着数据量变大,发现这个速度并不快,于是换了下面的方式

targetL = ['a', 'n', 'c', 'd']
targetD = dict.fromkeys(targetL, 0)

if item in targetD:
    other_operations

又可以愉快的查询了。

为什么呢?

这是因为:在Pyhton中列表的查询时间复杂度是O(n)(n是列表长度);字典的查询负责度是O(1)(与字典长度无关)。

字典的查询复杂度为什么是O(1)呢? Python中实现了一个hash函数,把字典的key转换为哈希值,组成连续地址的数字哈希表。字典的每次查询转换为了从数组特定位置取出一个元素,所以时间复杂度为O(1)

后来发现pythonset也是用hash table存储,所以上面的程序,可以更简化而不影响速度。

targetS = set(['a', 'n', 'c', 'd'])

if item in targetS:
    other_operations

那么速度到底差多大,有没有直观一些的展示呢? 这是StackOverflow的一个简化例子, 百万倍速度差异。

ct@ehbio:~$ python -mtimeit -s 'd=range(10**7)' '5*10**6 in d'

10 loops, best of 3: 182 msec per loop

ct@ehbio:~$ python -mtimeit -s 'd=dict.fromkeys(range(10**7))' '5*10**6 in d'

10000000 loops, best of 3: 0.16 usec per loop

ct@ehbio:~$ python -mtimeit -s 'd=set(range(10**7))' '5*10**6 in d'

10000000 loops, best of 3: 0.164 usec per loop

Ref:

标签:defaultdict,10,Python,为啥,复杂度,python,查找,key,字典
From: https://blog.51cto.com/u_16077014/6252731

相关文章

  • 为啥我的Python这么慢 (一)
    长假结束了,这不痛苦。痛苦的是长假结束了,发现写的基因组读取程序还没运行完?在Python系列教程中,我们提到一个概念字符串是不可修改的。这一点可以通过id函数来判断确实是对的。但是这个概念会对我们写作程序有什么影响一直没有特别深的理解。直到有一次,实验室一个朋友要读基因组数据......
  • 同行盆友来稿:初探Python变量
    什么是变量在Python编程语言中,变量是用于存储数据值的标识符。它们可以用来引用数据值,而不是直接使用值本身。可以使用等号(=)运算符来将一个值赋给一个变量。变量数据类型有那些变量类型有以下几种:1.整型(int):表示整数,例如:`42`、`-3`、`1000`等。2.浮点型(float):表示浮点数(即带......
  • Python程序与设计
    2-27在命令行窗口中启动的Python解释器中实现在Python自带的IDLE中实现print("Helloworld")编码规范每个import语句只导入一个模块,尽量避免一次导入多个模块不要在行尾添加分号“:”,也不要用分号将两条命令放在同一行建议每行不超过80个字符使用必要的空行可以增加代码的可读性运......
  • Python学习
    3-13字符串类型字符串类型:str   1.定义格式:       变量='内容'           打印一行       变量="内容"           打印一行       变量='''内容'''或者三引号           可以通过回车的方式换行,......
  • Python学习
    3-13字符串类型字符串类型:str   1.定义格式:       变量='内容'           打印一行       变量="内容"           打印一行       变量='''内容'''或者三引号           可以通过回车的方式换行,......
  • Python文本处理
     binascii—ConvertbetweenbinaryandASCII—Python3.11.3documentation Hackbright-challenges/hexconvert.pyatmaster·kritikadusad/Hackbright-challenges·GitHub hex2bin/hex2bin.pyatmain·jasonalexander-ja/hex2bin(github.com)importre......
  • 二分查找——出现溢出问题
    算法描述:前提:有已排序数组A(假设已经做好)定义左边界L、右边界R,确定搜索范围,循环执行二分查找(3、4两步)获取中间索引M=Floor((L+R)/2)中间索引的值A[M]与待搜索的值T进行比较①A[M]==T表示找到,返回中间索引②A[M]>T,中间值右侧的其它元素都大于T,无需......
  • 工作提效___python实现测试用例统计
    一、工作中存在的问题:1、被测项目不断迭代增加新功能,功能模块越来越多,用例采用excel文档进行记录,每个sheet代表一级功能模块,每个sheet里面会有多个二级功能模块。由于功能模块较多,导致测试用例文档中存在几十个sheet页2、由于项目测试中,很多测试用例可以共用一条测试用例,为了减......
  • 如何在Linux中查找一个文件
    《Linux就该这么学》-必读的Linux系统与红帽RHCE认证免费自学书籍免费电子版下载地址:https://www.linuxprobe.com/book导读对于新手而言,在Linux中使用命令行可能会非常不方便。没有图形界面,很难在不同文件夹间浏览,找到需要的文件。本篇教程中,我会展示如何在Linux中查找特......
  • Python wordpress-xmlrpc错误:xml.parsers.expat.ExpatError: XML or text declaration
    解决方法:修改打开client.py文件原代码:deffeed(self,data):self._parser.Parse(data,0)改成如下的代码:deffeed(self,data):self._parser.Parse(data.strip(),0)......