一、深入python的set和dict

1.1、dict的abc继承关系

from collections.abc import Mapping,MutableMapping
#dict属于mapping类型
a = {} #字典a不是继承MutableMapping,而是实现了MutableMapping的魔法函数
print(isinstance(a,MutableMapping)) #True

1.2、dict的常用方法

a = {"lishuntao":{"company":"hut"},
"lishuntao1":{"company":"hut1"}
}
#clear
# a.clear()
# print(a) #{} #copy,返回浅拷贝
# new_dict = a.copy()
# new_dict["lishuntao"]["company"] = "HUT" #new_dict拷贝出"lishuntao"与"lishuntao1"这是浅拷贝,
# # 第二层的dict也就是数据结构没有被拷贝出来,因此值会变动。
# print(new_dict) #{'lishuntao': {'company': 'HUT'}, 'lishuntao1': {'company': 'hut1'}}
# print(a) #{'lishuntao': {'company': 'HUT'}, 'lishuntao1': {'company': 'hut1'}} #深拷贝
import copy
new_dict = copy.deepcopy(a)
new_dict["lishuntao"]["company"] = "HUT"
print(a) #{'lishuntao': {'company': 'hut'}, 'lishuntao1': {'company': 'hut1'}}
print(new_dict) #{'lishuntao': {'company': 'HUT'}, 'lishuntao1': {'company': 'hut1'}} #fromkeys 将可迭代的对象转换为dict
new_list = ["li","li1","li2"]
new_dict = dict.fromkeys(new_list,{"company":"hut"})
print(new_dict) #{'li': {'company': 'hut'}, 'li1': {'company': 'hut'}, 'li2': {'company': 'hut'}} #get #如果没有这个键不会抛异常
value = a.get("lishuntao111",{})
print(value) #{} #items()
for key,value in a.items():
print(key,value) #lishuntao {'company': 'hut'},lishuntao1 {'company': 'hut1'} #setdefault
new_dict = a.setdefault("litao","hugongda")
print(new_dict) #hugongda
print(a) #{'lishuntao': {'company': 'hut'}, 'lishuntao1': {'company': 'hut1'}, 'litao': 'hugongda'} #update #可迭代的对象
#a.update([("lishun","tao"),("li110","hu")])
a.update(lishun='tao',li110="hu")#一样的效果

1.3、dict的子类

# #不建议继承dict和list
# class Mydict(dict):
# def __setitem__(self, key, value):
# super(Mydict, self).__setitem__(key,value*2)
#
# my_dict = Mydict(one=1)
# print(my_dict) #{'one': 1}
# my_dict["one"] = 1 #{'one': 2}
# print(my_dict)
# """
# 在某些情况下,用C语言写出来的python内置类型,它不会调用__setitem__方法
# 因此我们想要继承dict的话,就去继承UserDict(例如下面)
# """
from collections import UserDict
#
#
# class Mydict1(UserDict):
# def __setitem__(self, key, value):
# super(Mydict1, self).__setitem__(key,value*2)
#
# my_dict = Mydict1(one=1)
# print(my_dict) #{'one': 2}
# my_dict["one"] = 1 #{'one': 2}
# print(my_dict) from collections import defaultdict
"""
defaultdict重写了__missing__方法
"""
my_dict = defaultdict(dict)
my_value = my_dict["lishun"] #按照正常情况会报错误
print(my_value) #{} my_dict1 = {}
my_value1 = my_dict1["lishun"]
print(my_value1) #KeyError: 'lishun'

1.4、set和frozenset

#set 集合  frozenset 不可变集合   无序、不重复
s = set("abcde")
s.add("u")
print(s)#{'b', 'a', 'e', 'd', 'c', 'u'} s2 = frozenset("abcdef") #frozenset 可以作为dict的key
print(s2) #frozenset({'b', 'f', 'a', 'e', 'd', 'c'}) #不能修改 #difference
anoth_set = set("cdefgh")
res = s.difference(anoth_set)
print(res) #{'a', 'b', 'u'} #集合运算 交 并 差集
res = s - anoth_set
res1 = s & anoth_set #交
res2 = s | anoth_set #并
#set性能高 #实现__contains__魔法函数就可以做if判断

1.5、dict和set的实现原理

  dictlist查找元素,dict查找的性能远远大于list,在list中随着list数据的增大查找时间增大,在dict中查找元素不会随着数据的增大而增大,dict的实现原理叫做哈希表。哈希表的存储逻辑,哈希表的右边是数值的存储结构,是连续的数组,这个数组里存了指向keyvalue的指针。

哈希表的查找:首先计算dict的键的hash值,然后利用hash值定位数组中的一个表元,此时判断表元是否为空,如果表元为空,直接抛出KeyError,如果表元不为空,则判断键是否相等,如果相等的话返回表元里的值,如果不相等的话,则使用hash值的另一部分来定位hash表的另一行,然后又判断表元是否为空进入下一次判断循环。

 特性:

  1、dictkey或者set的值都必须是可以hash的(不可变对象,都是可以hash,str,frozenset,tuple,自己实现的类__hash__都是可以hash的)

  2、dict的内存花销大,但是查询速度快,自定义的对象或者python内部的对象都是用dict包装的

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

  4、添加数据有可能改变已有的数据的顺序

最新文章

  1. 数据库中的左连接(left join)和右连接(right join)区别
  2. 使用localResizeIMG微信压缩上传图片安卓报错 weixin://preInjectJSBridge/fail
  3. angular 控制器之间值得传递
  4. C++中的函数指针用法
  5. eclipse打开文件位置Open Explorer 插件
  6. 小技巧,把execl.exe转换成dll
  7. swing中几种layout示例(转)
  8. Tomcat下log4j设置文件路径和temp目录
  9. 1647: [Usaco2007 Open]Fliptile 翻格子游戏
  10. 附录D——自动微分(Autodiff)
  11. Java中在实例化一个类时,这个类中没有初始值的int类型成员变量i,i的值是不是0?
  12. iOS后台运行播放无声音频 测试可行
  13. base operand of '->' has non-pointer type 'const Comple
  14. PowerDesigner最基础的使用方法入门学习(二)
  15. [Jmeter] Concurrency Thread Group
  16. blob转base64位 base64位转blob
  17. WPF转换器:时间转换为字符串
  18. Windows 端口占用
  19. ICPC 沈阳 Problem C
  20. Codeforces Round #305 (Div. 1) B. Mike and Feet 单调栈

热门文章

  1. MariaDB和Apache安装
  2. maven中的setting文件
  3. Linux中docker的使用二
  4. ThinkPHP5——引入公共部分head和foot(多种方法)
  5. 【IoT平台技术对接分享】如何上传正确的消息推送证书
  6. Java修炼——面向对象的三大特征_多态_多态的三个必要条件
  7. LightOJ 1344 Aladdin and the Game of Bracelets
  8. 首次自动化测试,使用selenium+scapy
  9. 前端表单提交,提交有图片出现的问题,及解决方案 兼容ie9
  10. 2019年终总结:10场演讲、内推20人、公众号2万粉丝、Code Runner 1000万下载