美文网首页
为啥我的Python这么慢 - 项查找 (二)

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

作者: 生信宝典 | 来源:发表于2018-04-26 19:59 被阅读10次

欢迎关注天下博客:http://blog.genesino.com/2017/10/list-dict-set-speed/
上一篇为啥我的Python这么慢, 字符串的加和和join被陈群主分享到biopython-生信QQ群时,乐平指出字典的写法存在问题,并给了一篇知乎的链接https://zhuanlan.zhihu.com/p/28738634指导如何高效字典操作。

根据那篇文章改了两处写法,如下:

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遍历字典,节省近一半的内存。

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

time python readFaJoin2.py

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

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

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

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:

<footer class="entry-meta" style="box-sizing: border-box; display: block; font-size: 0.75rem; text-transform: uppercase; color: rgba(187, 187, 187, 0.8); margin: 50px 30px 30px; text-align: center; font-family: Lato, Calibri, Arial, sans-serif; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">PYTHONBIOINFOCHENTONG
版权声明:本文为博主原创文章,转载请注明出处。

alipay.png WeChatPay.png

</footer>

相关文章

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

    欢迎关注天下博客:http://blog.genesino.com/2017/10/list-dict-set-s...

  • 为啥我的Python这么慢 (一)

    欢迎关注生信宝典http://mp.weixin.qq.com/s/n5kkZfC8FGlzeBODarLHcw ...

  • 下班故事之赶地铁

    下班故事之赶地铁: 不上车的人,偏不急,要上车的人,急坏了,为啥这么慢,慢,慢,为啥这么急,急,急。 @_@

  • ICECREAM狂想

    起司的前生今世 问:为啥更新这么慢? 答:(跪)我错了......

  • 双指针(链表、数组)

    二分查找用于有序的排列python中的二分查找模块bisect,Python中的list.inidex时间复杂度是...

  • 算法之二分查找

    二分查找 二分查找是著名、高效并有应用广泛的查找算法。 二分常规实现 1.循环实现 下面我用python语言实现循...

  • python3安装

    一、完成Homebrew安装二、python安装 查找python3 ,命令:brew search python...

  • python二分查找

    python二分查找 # 查找数据import random# nums = [random.randint(1,...

  • 基础算法笔记 python和C++

    二分查找 python code 选择排序 python code c++ code 快速排序 python c++

  • 二分查找算法及分析

    二分查找 那么对于有序表, 有没有更好更快的查找算法? 在顺序查找中, 如果第1个数据项不匹配查找项的话, 那最多...

网友评论

      本文标题:为啥我的Python这么慢 - 项查找 (二)

      本文链接:https://www.haomeiwen.com/subject/slgmlftx.html