python的set与dict
上一篇的连接:菜鸟初学python入门进阶第四节:面向对象,自定义序列类
❤⭐🍦🍧🌈🌊🎉💄💻✨🎊🎏✨✨老铁萌球球点赞👍 评论📚
乱打的也可以
1.dict的abc继承关系🔥
dict属于map类型
先看看源码
from collections.abc import Mapping
点击abc,ctrl+b
from _collections_abc import *
from _collections_abc import __all__
ctrl+B进入all
__all__ = ["Awaitable", "Coroutine",
"AsyncIterable", "AsyncIterator", "AsyncGenerator",
"Hashable", "Iterable", "Iterator", "Generator", "Reversible",
"Sized", "Container", "Callable", "Collection",
"Set", "MutableSet",
"Mapping", "MutableMapping",
"MappingView", "KeysView", "ItemsView", "ValuesView",
"Sequence", "MutableSequence",
"ByteString",
]
看到"Mapping", "MutableMapping",
dict属于"MutableMapping"(可修改mapping)
再来ctrl+B
class MutableMapping(Mapping):
其继承了mapping
class Mapping(Collection):
mapping也是继承collection,所以某种程度上和序列类型有很多操作方法一样
2.再谈isinstance🔥
isinstance(实例, 某种类型)
isinstance方法还可以判断继承链
我们不妨看看isinstance的描述
def isinstance(x, A_tuple): # real signature unknown; restored from __doc__
"""
Return whether an object is an instance of a class or of a subclass thereof.
A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to
check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B)
or ...`` etc.
"""
pass
返回实例是否是该类或该类其中某个子类的实例
但是
from _collections_abc import *
from _collections_abc import __all__
a = {}
print(isinstance(a, MutableMapping))
输出
True
a是一个字典,但是当我们去看dict的继承关系
class dict(object):
dict却基本没有继承任何东西
a并不是真正继承了mutablemapping,只是实现了其中一些魔法函数
isinstance实际上是调用了register。
如果我们去mutablemapping类的末尾,可以看到
MutableMapping.register(dict)
dict被先注册在了mutablemapping里,仿佛预先知道 mutablemapping一定会有一个子类是dict。
这种方法不同于继承,这是注册,先注册将要有的子类,再在别处写该具体子类,子类不需要再继承基类,只需要实现注册该子类的基类中的魔法函数(协议)即可。
这和继承是反过来的。
不管是继承还是注册,这几个类都被连在了一条链上。
isinstance就是找这条链上的类。
3.dict的一些常见操作🔥
我们可以通过上述方法去查看dict的操作。
鉴于dict其实是用c语言写的,我们如果用pycharm,还是可以看到其用python的方式为我们展现了dict的描述和操作。这并不是真的逻辑,只是用代码的方式为我们展现文档。
常用操作如
a = {"a": {"b": "c"}}
a.clear()
就不赘述了。
浅拷贝和深拷贝:
a = {"a": {"b": "c"}}
b = a.copy()
import copy
c = copy.deepcopy(a)
b是浅拷贝的结果,实际上只是用一个新的指针指向原地址
c是深拷贝,是真正弄了一个备份,可以随意修改,不影响原来的数据
fromkeys方法:
这是个静态方法,可以为可迭代的对象增加值,并返回一个字典
l = ['a', 'b']
d = dict.fromkeys(l, 2)
print(d)
输出
{'a': 2, 'b': 2}
get方法:
xxx = xx.get(“key”,默认值)
items方法:
a = {"a": {"b": "c"}, "d": "e"}
for key, value in a.items():
print(key, value)
输出
a {'b': 'c'}
d e
setdefault方法:
不仅将值取出来,还加进原字典里
a = {"a": {"b": "c"}, "d": "e"}
j = a.setdefault("f", 'g')
print(j)
print(a)
输出
g
{'a': {'b': 'c'}, 'd': 'e', 'f': 'g'}
update方法:
有点像extend,放可迭代的字典就行
a = {"a": {"b": "c"}, "d": "e"}
a.update(aa="aa",bb="bb",cc="cc",dd="dd")
print(a)
输出
{'a': {'b': 'c'}, 'd': 'e', 'aa': 'aa', 'bb': 'bb', 'cc': 'cc', 'dd': 'dd'}
4.dict的一些子类🔥
UserDict
鉴于dict其实是用c语言写的,不建议继承dict或list
一般使用继承UserDict
from collections import UserDict
class nDict(UserDict):
def __setitem__(self, key, value):
super().__setitem__(key, value)
defauldict
from collections import defaultdict
class defaultdict(dict):
"""
defaultdict(default_factory[, ...]) --> dict with default factory
The default factory is called without arguments to produce
a new value when a key is not present, in __getitem__ only.
A defaultdict compares equal to a dict with the same items.
All remaining arguments are treated the same as if they were
passed to the dict constructor, including keyword arguments.
"""
defaudict主要是重写了missing方法,dict属于mutablemapping,mutablemapping里面的getitem方法会调用missing方法。
defaudict如果找不到键,会默认返回空列表
def __missing__(self, key): # real signature unknown; restored from __doc__
"""
__missing__(key) # Called by __getitem__ for missing key; pseudo-code:
if self.default_factory is None: raise KeyError((key,))
self[key] = value = self.default_factory()
return value
"""
pass
使用:
from collections import defaultdict
a = {"a": {"b": "c"}, "d": "e"}
b = defaultdict(dict, a)
c = b['sb']
print(c)
输出
{'a': {'b': 'c'}, 'd': 'e', 'aa': 'aa', 'bb': 'bb', 'cc': 'cc', 'dd': 'dd'}
{}
5.set与frozenset🔥
集合与不可变集合。
集合无序,不重复。
frosenset没有add方法。
set有很多的方法,也实现了很多魔法函数,性能很高。
简单方法看文档即可
6.dict与set的实现原理🔥
dict查找的性能远远大于list。在list中随着数据增大,查找时间增加,而在dict中查找时间不会增加。
dict实际上是个哈希表
set也是哈希表
dict的key和set的值,都必须是可以哈希的。
而不可变对象都是可哈希的,如str、frosenset、tuple。
我们可以通过实现魔法函数hash来让自定义类返回特定的值,把自定义类变成可哈希的,再放到dict的key和set的值中。
dict的内存花销大,但找的快。
dict的储存顺序和元素添加顺序有关,且加入数据可能改变已有数据的顺序。
就到这里😙😙
下一篇的连接:菜鸟初学python入门进阶第六节:面向对象,引用、可变性与垃圾回收
❤⭐🍦🍧🌈🌊🎉💄💻✨🎊🎏✨✨d=====( ̄▽ ̄*)b
U•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*UU•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*U-U•ェ•*U-