文章目录
- 1. dict和abc的继承关系
- 2. dict的常用方法
- 2.1 浅拷贝和深拷贝的区别
- 2.2 fromkeys方法
- 2.3 get方法
- 2.4 items方法
- 2.5 setdefault方法
- 2.6 update方法
- 3. dict的子类
- 4. set和frozenset
- 4.1 set,frozenset的基本操作
- 4.2 ( | & - ) 集合操作
- 5. 浅谈set和dict的实现原理
1. dict和abc的继承关系
在collections.abc中进入abc模块跟进__all__模块
🌙 :在__all__中存在Mapping和MutableMapping,MutableMapping继承Mapping,Mapping继承collections
a = {
"Name": {"张三": "18"}, "性别": {"男", "25"}
}
if __name__ == '__main__':
print(isinstance(a, MutableMapping)) #输出True
🌙: 根据代码结果dict是MutableMapping类型的对象,所以继承他们内部的魔法函数以及方法
2. dict的常用方法
2.1 浅拷贝和深拷贝的区别
浅拷贝代码:
a = {
"Name": {"张三": "18"}, "性别": {"男", "25"}
}
if __name__ == '__main__':
new_dict = a.copy()
new_dict["Name"]["男"]="完成"
print(new_dict)
print(a) #浅拷贝
#输出的两个dict都是相同的值
(deepcopy)深拷贝代码:
a = {
"Name": {"张三": "18"}, "性别": {"男", "25"}
}
if __name__ == '__main__':
new_dict = copy.deepcopy(a)
new_dict["Name"]["男"]="完成"
print(new_dict)
print(a)# 深拷贝
#不会改变原dict a dict不会改变
2.2 fromkeys方法
new_dict = ["name", "sex"] # 列表
new_dict = dict.fromkeys(new_dict, {"张三", "男"})
print(new_dict) # 把可迭代对象变成建值
#输出结果 {'name': {'男', '张三'}, 'sex': {'男', '张三'}}
2.3 get方法
new_dict = ["name", "sex"]
new_dict = dict.fromkeys(new_dict, {"张三", "男"})
print(type(new_dict)) #dict对象
new_dict["GGGG"] # 当dict中没有这个key时会报错 keyError错误
🌙 :为了防止出现上面的赋值错误,python用了get方法来解决,用代码说明:
new_dict = ["name", "sex"]
new_dict = dict.fromkeys(new_dict, {"张三", "男"})
value = new_dict.get("GGGG",{}) #直接在get中定义
value = new_dict.get("name", {}) #直接取出name的value值
if __name__ == '__main__':
print(value)
2.4 items方法
new_dict = ["name", "sex"]
new_dict = dict.fromkeys(new_dict, {"张三", "男"})
if __name__ == '__main__':
for key, value in new_dict.items(): # items遍历 不加取key
print(key, value) #分别取出key value
for key in new_dict:
print(key) #只能获取key
2.5 setdefault方法
new_dict = ["name", "sex"]
new_dict = dict.fromkeys(new_dict, {"张三", "男"})
if __name__ == '__main__':
value = new_dict.setdefault("age", 18) # 添加值
print(value) #添加dict的同时可以取出value值
print(new_dict)
# setdefault的执行效率高
2.6 update方法
new_dict = ["name", "sex"]
new_dict = dict.fromkeys(new_dict, {"张三", "男"})
if __name__ == '__main__':
#update两种添加值的方式
new_dict.update({"bobby": "lmocc"}) # 添加可迭代的对象
new_dict.update(bobby=1)
print(new_dict)
🌙:在pyton中还有很多这样的内部方法,可以跟进dict内部查看和使用
3. dict的子类
🌙 :通常在些类的时候,尽量不要去继承list和dict,这里我用代码块去解释继承list和dict出现的一些问题。
class Demo(dict):
def __setitem__(self, key, value):
super().__setitem__(key,value*2)
mydict = Demo(one=1) # 不调用重写的方法
print(mydict) #输出{'one': 1}
mydict["one"] = 1 #调用重写方法
print(mydict) #输出{'one': 2}
🌙:上述代码中,在Demo中重写了__setitem__魔法函数,在默认的情况下创建对象会直接去run(setitem)函数,当继承dict或者list的时候dict会不执行__setitem__,直接赋值了,继承list则上述代码会直接报错。如果用户就是要继承dict也可以,这时需要使用到collections的子类UserDict 。
class Demo(UserDict): # 继承UserDict 可以不覆盖内部实现的方法
def __setitem__(self, key, value):
super().__setitem__(key,value*2)
mydict = Demo(one=1)
print(mydict) #输出{'one': 2}
dict的defaultdict 子类:
from collections import defaultdict #dict的子类
my_dict = defaultdict(dict)
my_value = my_dict["bobby"]
print(my_value) #输出{}
# defaultdict 还有很多用法, 本章不细讲
4. set和frozenset
4.1 set,frozenset的基本操作
🌙:set 集合 frozenset (不可变集合) 无序 不重复,set的查找性能非常的快
s0 = set("ancdaaaaaefg")
print(s0) #输出 {'g', 'e', 'c', 'n', 'f', 'd', 'a'} 去重
#添加数据
s2 = s0.update("abcd") #添加 update这个方法是没有返回值的
s0.add(2) #添加 只能添加一个元素
print(s0) #应该输出s0 结果 {'e', 'a', 'd', 'f', 'g', 'n', 'c', 'b'}
frozenset 的操作:
s = frozenset("abcde")
print(s) #和set一样的赋值
#frozenset是不可变的 所以没有增删改的方法 不可变 可以作为dict的key
difference方法
s2 = frozenset("abcde")
s1 = set("ancdaaaaaefg")
s3 = s1.difference(s2) #取差集
print(s3) #打印 {'f', 'g', 'n'}
4.2 ( | & - ) 集合操作
s0 = set("abcdefg")
s1 = set("afe")
if __name__ == '__main__':
re_set = s0 - s1
re_set1 = s0 & s1
re_set2 = s0 | s1
print(re_set) #{'g', 'c', 'b', 'd'} 取差集
print(re_set1) #{'f', 'e', 'a'} 取交集
print(re_set2) #{'c', 'd', 'g', 'a', 'b', 'f', 'e'} 取并集
🌙:为什么可以在集合中直接使用这些符号计算?下面跟进内部魔法函数可以发现内部存在实现功能。
| 的运算的魔法函数
&的运算魔法函数
- 号的运算魔法函数
5. 浅谈set和dict的实现原理
🌙 在非常多的数据中查询指定的值,使用set和dict的速度非常的快,远高于list的查询操作,数据值越大越能体现高性能,因为在dict或者set中查找元素 不会随着dict或set的增大而增大,性能高的原因是因为在set和dict的底层使用了哈希表进行了查询,深入的讲解哈希表又是一篇长文,这里笔者只浅谈,只表述set和dict的底层使用哈希表查询。