zoukankan      html  css  js  c++  java
  • Python字典的实现原理

    几个问题?

    • Python里的dict和set效率有多高?
    • 为什么它们是无序的?
    • 为什么并不是所有的Pythoon对象都可以当作dict的键或set里的元素?
    • 为什么dict的键和set元素的顺序是根据它们被添加的次序而定的,以及为什么在映射对象的生命周期中,这个顺序并不是一成不变的?
    • 为什么不应该在迭代循环dict或是set的同时往里添加元素?
     
     

     字典的散列表

    散列表是一个稀疏数组(总是有空白元素的数组)。
    散列表里的单元通常叫做表元。dict的散列表中,每个键值对都占用一个表元,表元都有两部分,一个是对键的引用,一个是对值的引用。
     
    Python会设法保证大概还有三分之一的表元是空的;
     
    如果要把一个对象放入散列表,首先要计算这个元素的散列值。(Python会用到hash方法);
     
    散列表算法
     
    添加新元素和更新现有键值的操作几乎和上面一样;
    前者在发现空表元时会放入一个新元素;对于后者,在找到对应的表元后,原表里的值对象会被替换成新值。
     
    在插入新值时,Python可能会按照散列表的拥挤程度来决定是否要重新分配内存为它扩容。增加了散列表的大小,那散列值所占的位数和用作索引的位数都会增加,目的是为了减少发送散列冲突的概率。
     
     

    dict的实现及优缺点【实际就是以空间换时间】

     
    1、键必须是可散列的
    可散列对象必须满足以下要求:
    1. 支持hash()函数,并通过__hash__()方法所得到的散列值是不变的;
    2. 支持通过__eq__()方法来检测相等性;
    3. 若a==b为真,则hash(a)==hash(b)也为真。
     
    2、字典在内存上开销巨大
    使用了散列表,而散列表又必须是稀疏的,导致空间上的效率低下。
     
    3、键查询很快
    字典类型有着巨大的内存开销,但它们提供了无视数据量大小的快速访问。
     
    4、键的次序取决于添加顺序
    当往dict里添加新键而又发生散列冲突的时候,新键可能会被安排存放到另一个位置。
     
    5、往字典里添加新键可能会改变已有键的顺序
    无论何时往字典里添加新的键,Python解释器都可能做出为字典扩容的决定。
    扩容导致的结果就是要新建一个更大的散列表,并把字典里已有的元素添加到新表里。可能会发生新的散列冲突,导致新散列表中键的次序变化。
     
     
    备注:
        1、不要对字典同时进行迭代和修改
        2、dict.keys()、dict.values()、dict.items()返回的是一个字典视图对象,不是列表。更像是集合,可以迭代。
     
     
    example
    # 尝试在迭代时去修改字典
    for
    key, value in c.items(): if max_values == value: if key == ignore_word: del c[key]
     
     
     
     
     
     
    人生的路还很长,继续走吧
  • 相关阅读:
    Python day43 :pymysql模块/查询,插入,删除操作/SQL注入完全问题/事务/模拟登录注册服务器/视图/函数/存储过程
    docker
    Linux 05
    Linux04
    Linux 03
    Linux 02
    go语言
    go语言
    go语言
    Linux
  • 原文地址:https://www.cnblogs.com/jinggs/p/15118430.html
Copyright © 2011-2022 走看看