• python3.6前后版本,字典底层原理


    python字典底层原理

    python3.6以前字典是不能保证顺序的,3.6及其以后变为有序,dict主要遵循的是key的插入顺序
    

    python3.6版本以前

    '''存值时''':
    初始化一个空的字典,cpython底层会初始化一个二维数组,数组8行3列;首先会对key值进行hash,得到当前状态下的hash值,这个hash值对8进行求余,得到余数,然后将要存的数据放到初始化数组的下标为该余数的这一行,第一列放hash值,第二列放指向key的指针,第三列放指向value的指针
    
    '''取值时''':
    key的hash值对8进行求余,在二维数组下标为余数的这一行就是所需的键值对,通过地址值获取到内存中数据
    '''
    由于hash值取余数后,余数可大可小,所以字典key并不是按照插入的顺序存放的
    '''
    # 1.当两个不同的key,经过hash,对8进行取余,可能最后的余数是一样的,就会使用开放寻址法,重新寻找一个新的位置
    # 2.开放寻址的三种算法是线性探查,二次探查和双重散列;对于相邻的位置,选择的几率比较大
    # 3.当字典的键值对数量超过数组长度的2/3时,数组会扩容,8行变16行,16行变32行,长度变了,原来的余数的位置就变了,此时就需要移动原来位置的数据,导致了插入效率变低
    

    python3.6及以后版本

    '''存值时'''
    初始化一个空的字典,python单独生成了一个长度为8的一维数组indices,然后又生成了一个空的二维数组entries,对key进行hash,得到hash值,再对8进行求余,得到余数,再修改一维数组中对应下标为该余数的地方,第一次就改为0,0就是这个键值对在这个二维数组的行索引,才是二维数组只有一行数据,第一列为hash值,第二列为key所对应的指针,第三列则为value对应的指针
    
    '''取值时'''
    hash值对8进行求余,拿到一维数组中下标为该余数的索引,再去二维数组中找到下标为该索引的值,便能拿到键值对
    '''
    这种方式在遍历时,二维数组entries每一行数据都是有用的,不用再跳过,所以效率比较高
    '''
    

    二者内存占用的比较

    '''假设在数组中,有效的数据都是三行'''
    在3.6以前,每列8个字节,每行有三列,24个字节,共8行,所以占用的资源是8*24=192byte,而在3.6及其以后,indices数组占用8byte, entries数组占用3*24,所以共占用资源80byte
    
  • 相关阅读:
    ASP.NET 如何取得 Request URL 的各個部分
    正则表达式
    sql server 存储过程中拼接sql,转义单引号
    C# 过滤敏感字符
    Facebook “Invite” 弹出窗口
    Silverlight 4 动态换Theme
    silverlight 4 com组件调用
    Silverlight 4 COM+ 操作支持示例集
    如何创建silverlight离开浏览器的应用程序
    Silverlight 4 的 WCF NET.TCP 协议
  • 原文地址:https://www.cnblogs.com/godlover/p/14310028.html
Copyright © 2020-2023  润新知