python高级编程(5) - 深入python的dict和set

深入python的dict和set

一,dict的abc继承关系

dict 的抽象基类是 Mapping

from collections import Mapping
d = {}
print(isinstance(d, Mapping))

二,dict的常用方法

…自己脑补

三,dict的子类

不要去继承 dictset ,他们内部是用c语言写的,使用父类的方法有时不会被调用

如果要继承,使用 collections.UserDict,这个用 python 重写过字典的,继承之后调用父类的方法没有问题

四,set和frozenset

set 可变集合,fronzenset(不可变集合)

  1. set 可变集合

    # 无序并且不重复,不能修改里面的值
    s = set('abdefgabcdefg')
    print(s)
    
  2. fronzenset 不可变集合,可以作为字典的 key

    s = frozenset('abcdefgabcdefg')
    print(s)
    

五,dict和set的实现原理

dictlist 对比

  1. dict 的性能远远大于 list
  2. list 中,查找元素是随着数据的翻倍成倍增加
  3. dict 中查找元素,不会随着 dict 的增大而增大
  • 实现原理

    • pythondict中间进行查找某个key操作时,查找所需时间不会随着dict中键值对数量增多而变长,(时间复杂度为O(1))但是list中就会(时间复杂度为O(N)),这是因为list查询实现的方式是循环遍历所有列表,然后查找对应的元素,所以列表中元素越多,查找越费时间,但是同一个dict中的所有keyid在内存中是连续的,并且其数据的存储方式为hash表的形式,原理图如下

      python高级编程(5) - 深入python的dict和set_第1张图片

      python高级编程(5) - 深入python的dict和set_第2张图片

dict中的key会调用内置的hash()方法(如果是自定义的类就会调用自定义的hash,把hash()得到的新key作为 索引或者说数组下标,找到位置把keyvalue的引用一起存入数组中

因为本质上是数组,所以通过偏移量就能查找到对应的目标

因此:

  1. dictkey 或者 set的值都必须是可hash的不可变对象,都是可hash的,strfronzenset, tuple, 自己实现的类(带有**__ hash __**魔法函数)

  2. dict 的内存花销大(hash简单的来说即映射,映射之后,不可能是连续的存在内存空间中的,总有一些内存时空的,当发现内存空间中的“空”只有1/3时,便会触发扩容操作,以免引起hash冲突),但是查询速度快。自定义的对象,或者python内部的对象都是dict包装的。

  3. dict的存储顺序和元素的添加顺序有关

  4. 添加的数据有可能改变已有的数据顺序(扩容时,需要将原来的dict,复制移动到新的内存空间,此时将“挤出”已有的“空”,所以每个key的偏移可能改变)

你可能感兴趣的:(python高级编程并发编程)