前言:

我一直觉得对我来说学习知识很忌讳不系统。本篇内容与上一篇 自定义序列类是有联系的。

上一篇比较通范的了解了序列类的一些协议和特性,并且有些list的内容。这篇更加具体到set和dict这两个序列类。

以此来了解python序列类的具体应用。(这篇比较简单)(感觉具体比抽象都更容易理解,但是也要学会思考把具体对象抽象化来表达,即提取共性)

content:

1.dict在abc中的序列类型和继承关系

2.dict实现了的常用方法

3.我可不可以继承dict这种序列类?

4.set和frozenset

5.set和dict的原理

==============

1.dict在abc中的序列类型和继承关系

dict在collection.abc中,实际上是属于MutableMapping(可变mapping)类型。

跟上篇对可变序列类继承的分析一样,MutableMapping继承了Mapping的一些功能并且加了一些可变的特性,

Mapping继承了Collection。接下来的继承和上篇的一样。

2.dict实现了的常用方法

如果用的是pycharm,还是用ctrl+b就能跳到python对dict的定义。

常用:

a = {"":{"a":"aa"},
"":{"b":"bb"}} # 清空字典
a.clear() # 浅拷贝字典 浅拷贝虽然可以正常赋值,但是如果 my_dopy_dict 中的值进行了改变,则 a 中的值也会进行对应的改变
my_dopy_dict = a.copy() # 深拷贝 深拷贝则是实实在在的在内存当中声明了一个新的变量
import copy
new_dict = copy.deepcopy(a) # get函数 dict.get(要查找的key,如果没找到对应key的内容返回的数据)
print(a.get("",{1:""})) # {1: '3'} # dict.fromkeys() 函数用于创建一个新字典,以序列 seq 中元素做字典的键 seq可以是可迭代的,value 为字典所有键对应的初始值。
my_list = [1, 2, 3]
my_new_dict = dict.fromkeys(my_list, {"":""}) #{1: {'222': '3434'}, 2: {'222': '3434'}, 3: {'222': '3434'}} # setdefault() 函数和 get()方法 类似,
# 如果键不存在于字典中,将会添加键并将值设为默认值。
# 如果存在,则将会返回该key对应的value
a.setdefault("", "cc") # a= {'1': {'a': 'aa'}, '2': {'b': 'bb'}, '3': 'cc'}
print(a.setdefault("", "cc")) # 返回{'b': 'bb'} # update() 函数把字典dict2的键/值对更新到dict里。
# 如果字典b中有与a相同的key,则会把a中的key对应的value进行更新
# 如果字典b中有a中没有的key,则a会将未有的key与value添加进去
b = {"": "cc", "": "dd"}
a.update(b)
print(a) # {'1': {'a': 'aa'}, '2': 'dd', '3': 'cc'}

3.我可不可以继承dict这种序列类?(dict的子类)

a.如果我偷懒想实现dict这种类型,能不能直接继承这种序列类呢?同理list是否可以?

例:继承dict,并且重写设置dict key的value时调用的魔法函数,使其值变为2倍

class Mydict(dict):
def __setitem__(self, key, value):
super().__setitem__(key, value*2) a=Mydict(b=1)
print(a) a['b']=1
print(a)

输出:

可以发现,原来同样功能和效果的,我们重写方法后,第一种方法去设置key的value值这一操作并没有调用我们重写的方法。

所以并不建议去继承python的这种序列类。

b.有没有什么办法我实在想继承?

python里专门给了个UserDict类,可以实现想要的继承Dict类的效果

from collections import UserDict
class Mydict(UserDict):
def __setitem__(self, key, value):
super().__setitem__(key, value*2) mydict = Mydict(one = 1) # {'one': 2} 调用__setitem__这个魔法函数
mydict["one"] = 2 # {'one': 4} 这种方式也可以调用__setitem__

输出:

 c.python中Dcit实际也有子类实现:defaultdict

使用:

from collections import defaultdict # 这个是dict的子类
mydict = defaultdict(dict)
myvalue = mydict["bai"] # 如果不存在的话,返回{}

输出:

4.set和frozenset

a.两者是啥有啥特点?

set:集合(无序,不重复,可变)

frozenset:不可变集合(无序,不重复,不可变)

frozenset没有改变的方法 一旦初始化了 就不可变了。其中,不可变类型对可变类型的一个特点,不可变类型是可以作为dict的key的。
 
b.set常用操作
a=set('abcdee')
a.add('f')
print(a)
another_set=set('defgh')
#添加数据
#a.update(another_set)
#print(a)
#集合的差集
re_set=a.difference(another_set)
#减法实现于__ior__魔法函数
re_set2=a-another_set
#集合的交集&
re_set3=a&another_set
#集合的并集|
re_set4=a|another_set
print(re_set)
print(re_set2)
print(re_set3)
print(re_set4)
#也可以用if in判断(实现于__contains__魔法函数)
if 'a' in re_set:
print('I am a set')

5.set和dict的原理

之前就提过,set的性能棒的。dict的查询性能远比起list要好。

并且list中随着list数据的增大,查找时间会增大,而dict不会。

这是为什么呢?

因为dict使用hash这种数据结构存储。set也是。

a.dict的散列表

特点:

- dict的key必须是可hash的,不可hash的是不能当成dict的key的,比如list
- python申请内存的时候,会初始化一个小的连续的空空间
- 由上一条可得这样 一定会存在浪费,这时候每次变动操作 会计算剩余空间,剩余空间小于1/3的时候,会重新生成空间并且将现在数据都拷贝过去(rehash)
- 数组比这种链表结构好的地方,就是可以直接根据偏移量来存取,而不用全部开始从头遍历。
(这种结构hash和重hash的策略用在很多地方,包括redis等)
 
b.存储结构了解了,那么数据的查找过程呢?

先计算a的散列值,查找表源是否为空,

因为a是不变的,所以如果表源为空,那么就会抛出key error。

如果表源不为空,也有可能是其他key,查看key是否是要查找的key。

如果是其他key,重新散列循环查找。

c.这种hash结构在python中的特点

- 我们可以用__hash__这个魔法函数实现可hash对象

- dict内存开销比较大,这是hash表的特点。

- 实际上python内部类和对象,都是dict。

- dict存储顺序和元素添加顺序有关。

- 插入数据后检查剩余空间引发的重hash,会影响原来的数据(比如地址)。

PythonI/O进阶学习笔记_5.python的set和dict的更多相关文章

  1. PythonI/O进阶学习笔记_8.python的可迭代对象和迭代器、迭代设计模式

     content: 1.什么是迭代协议 2. 什么是迭代器(Iterator)和可迭代对象(Iterable) 3. 使用迭代器和可迭代对象 4. 创建迭代器和可迭代对象 5. 迭代器设计模式   一 ...

  2. PythonI/O进阶学习笔记_10.python的多线程

     content: 1. python的GIL 2. 多线程编程简单示例 3. 线程间的通信 4. 线程池 5. threadpool Future 源码分析   ================== ...

  3. PythonI/O进阶学习笔记_7.python动态属性,__new__和__init__和元类编程(上)

    content: 上: 1.property动态属性 2.__getattr__和__setattr__的区别和在属性查找中的作用 3.属性描述符 和属性查找过程 4.__new__和__init__ ...

  4. PythonI/O进阶学习笔记_9.python的生成器

     content: 1. 什么是生成器 2. 生成器的实现 3. 生成器的应用   一.生成器简介 1.什么是生成器     在 Python 中,使用了 yield 的函数被称为生成器(genera ...

  5. PythonI/O进阶学习笔记_11.python的多进程

    content: 1. 为什么要多进程编程?和多线程有什么区别? 2. python 多进程编程 3. 进程间通信 =======================================   ...

  6. PythonI/O进阶学习笔记_1.抽象、面向对象、class/object/type

    前言: 是自己在学习python进阶IO学习视频的时候的理解和笔记,因为很多都是本菜鸟学习时候的自己的理解,有可能理解有误. Content: - 抽象的概念和面向对象的概念?想要大概了解python ...

  7. PythonI/O进阶学习笔记_3.2面向对象编程_python的继承(多继承/super/MRO/抽象基类/mixin模式)

    前言: 本篇相关内容分为3篇多态.继承.封装,这篇为第二篇 继承. 本篇内容围绕 python基础教程这段: 在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法.使 ...

  8. PythonI/O进阶学习笔记_6.对象引用,可变性和垃圾回收

    前言: 没有前言了- -......这系列是整理的以前的笔记上传的,有些我自己都忘记我当时记笔记的关联关系了. 记住以后 笔记记了就是用来复习的!!!不看不就啥用没了吗!!! content: 1.p ...

  9. PythonI/O进阶学习笔记_3.1面向对象编程_python的多态和鸭子类型

    前言: 与第一篇的面向对象内容不同的是,第一篇中的面向对象更多的是与类.对象结合起来的概念粗浅理解,就是在编程历史中诞生的一种思想方法. 这篇的面向对象编程,更多落实到在语言设计实现中,是如何体现面向 ...

随机推荐

  1. APP启动优化

    1. 去除启动黑屏 1.1 在style.xml中定义两种主题: <style name="AppTheme" parent="Theme.AppCompat.Da ...

  2. pdf.js跨域加载文件

    pdf.js一个基于Html的工具类,熟悉pdf.js的朋友们很清楚,pdf.js帮助我们做了很多事.尤其金融类网站会产生很多的报表.需要在线预览.pdf.js绝对是我们的首选 本地预览 在pdf.j ...

  3. 谈谈我对Ext的认识,元芳,你怎么看

    实用Ext第一步当然是引用jar包啦. 下载地址 在页面上加上div用于显示这也是必须的 <div id='loginpanel' ></div> 在js中我们肯定需要将Ext ...

  4. 免费IP代理池定时维护,封装通用爬虫工具类每次随机更新IP代理池跟UserAgent池,并制作简易流量爬虫

    前言 我们之前的爬虫都是模拟成浏览器后直接爬取,并没有动态设置IP代理以及UserAgent标识,本文记录免费IP代理池定时维护,封装通用爬虫工具类每次随机更新IP代理池跟UserAgent池,并制作 ...

  5. Kafka单线程Consumer及参数详解

    请使用0.9以后的版本: 示例代码 Properties props = new Properties(); props.put("bootstrap.servers", &quo ...

  6. python3 how to creat alphabet

    Python: How To Generate a List Of Letters In The Alphabet  Method 1# First we need to figure out the ...

  7. Mybatis mapper动态代理的原理详解

    在开始动态代理的原理讲解以前,我们先看一下集成mybatis以后dao层不使用动态代理以及使用动态代理的两种实现方式,通过对比我们自己实现dao层接口以及mybatis动态代理可以更加直观的展现出my ...

  8. ansible模块介绍之ios_command

    一.模块简介 ios_command此模块将任意命令发送到ios节点并返回设备读取的结果 此模块不支持在配置模式下使用,即只支持在用户模式>和特权模式#下使用 官方文档地址:https://do ...

  9. 【Spring Boot】利用 Spring Boot Admin 进行项目监控管理

    利用 Spring Boot Admin 进行项目监控管理 一.Spring Boot Admin 是什么 Spring Boot Admin (SBA) 是一个社区开源项目,用于管理和监视 Spri ...

  10. 用python解析JSON

    先来认识下JSON JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使 ...